Auto merge of #133858 - dianne:better-blame-constraints-for-static, r=lcnr
`best_blame_constraint`: Blame better constraints when the region graph has cycles from invariance or `'static`
This fixes #132749 by changing which constraint is blamed for region errors in several cases. `best_blame_constraint` had a heuristic that tried to pinpoint the constraint causing an error by filtering out any constraints where the outliving region is unified with the ultimate target region being outlived. However, it used the SCCs of the region graph to do this, which is unreliable; in particular, if the target region is `'static`, or if there are cycles from the presence of invariant types, it was skipping over the constraints it should be blaming. As is the case in that issue, this could lead to confusing diagnostics. The simplest fix seems to work decently, judging by test stderr: this makes `best_blame_constraint` no longer filter constraints by their outliving region's SCC.
There are admittedly some quirks in the test output. In many cases, subdiagnostics that depend on the particular constraint being blamed have either started or stopped being emitted. After starting at this for quite a while, I think anything too fickle about whether it outputs based on the particular constraint being blamed should instead be looking at the constraint path as a whole, similar to what's done for [the placeholder-from-predicate note](https://github.com/rust-lang/rust/compare/master...dianne:rust:better-blame-constraints-for-static#diff-3c0de6462469af483c9ecdf2c4b00cb26192218ef2d5c62a0fde75107a74caaeR506).
Very many tests involving invariant types gained a note pointing out the types' invariance, but in a few cases it was lost. A particularly illustrative example is [tests/ui/lifetimes/copy_modulo_regions.stderr](https://github.com/rust-lang/rust/compare/master...dianne:rust:better-blame-constraints-for-static?expand=1#diff-96e1f8b29789b3c4ce2f77a5e0fba248829b97ef9d1ce39e7d2b4aa57b2cf4f0); I'd argue the new constraint is a better one to blame, but it lacks the variance diagnostic information that's elsewhere in the constraint path. If desired, I can try making that note check the whole path rather than just the blamed constraint.
The subdiagnostic [`BorrowExplanation::add_object_lifetime_default_note`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/diagnostics/explain_borrow/enum.BorrowExplanation.html#method.add_object_lifetime_default_note) depends on a `Cast` being blamed, so [a special case](364ca7f99c
) was necessary to keep it from disappearing from tests specifically testing for it. However, see the FIXME comment in that commit; I think the special case should be removed once that subdiagnostic works properly, but it's nontrivial enough to warrant a separate PR. Incidentally, this removes the note from a test where it was being added erroneously: in [tests/ui/borrowck/two-phase-surprise-no-conflict.stderr](https://github.com/rust-lang/rust/compare/master...dianne:rust:better-blame-constraints-for-static?expand=1#diff-8cf085af8203677de6575a45458c9e6b03412a927df879412adec7e4f7ff5e14), the object lifetime is explicitly provided and it's not `'static`.
This commit is contained in:
commit
6afee111c2
99 changed files with 731 additions and 620 deletions
|
@ -4115,7 +4115,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",
|
||||||
|
|
|
@ -1516,15 +1516,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||||
.add_explanation_to_diagnostic(
|
.add_explanation_to_diagnostic(&self, &mut err, "", Some(borrow_span), None);
|
||||||
self.infcx.tcx,
|
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
Some(borrow_span),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
self.suggest_copy_for_type_in_cloned_ref(&mut err, place);
|
self.suggest_copy_for_type_in_cloned_ref(&mut err, place);
|
||||||
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
|
let typeck_results = self.infcx.tcx.typeck(self.mir_def_id());
|
||||||
if let Some(expr) = self.find_expr(borrow_span) {
|
if let Some(expr) = self.find_expr(borrow_span) {
|
||||||
|
@ -1591,15 +1583,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||||
.add_explanation_to_diagnostic(
|
.add_explanation_to_diagnostic(&self, &mut err, "", None, None);
|
||||||
self.infcx.tcx,
|
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1886,9 +1870,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
explanation.add_explanation_to_diagnostic(
|
explanation.add_explanation_to_diagnostic(
|
||||||
self.infcx.tcx,
|
&self,
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
&mut err,
|
||||||
first_borrow_desc,
|
first_borrow_desc,
|
||||||
None,
|
None,
|
||||||
|
@ -3046,15 +3028,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
|
|
||||||
if let BorrowExplanation::MustBeValidFor { .. } = explanation {
|
if let BorrowExplanation::MustBeValidFor { .. } = explanation {
|
||||||
} else {
|
} else {
|
||||||
explanation.add_explanation_to_diagnostic(
|
explanation.add_explanation_to_diagnostic(&self, &mut err, "", None, None);
|
||||||
self.infcx.tcx,
|
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err.span_label(borrow_span, "borrowed value does not live long enough");
|
err.span_label(borrow_span, "borrowed value does not live long enough");
|
||||||
|
@ -3067,15 +3041,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
explanation.add_explanation_to_diagnostic(
|
explanation.add_explanation_to_diagnostic(&self, &mut err, "", Some(borrow_span), None);
|
||||||
self.infcx.tcx,
|
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
Some(borrow_span),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err
|
err
|
||||||
|
@ -3128,15 +3094,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
explanation.add_explanation_to_diagnostic(
|
explanation.add_explanation_to_diagnostic(&self, &mut err, "", None, None);
|
||||||
self.infcx.tcx,
|
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.buffer_error(err);
|
self.buffer_error(err);
|
||||||
}
|
}
|
||||||
|
@ -3309,15 +3267,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
explanation.add_explanation_to_diagnostic(
|
explanation.add_explanation_to_diagnostic(&self, &mut err, "", None, None);
|
||||||
self.infcx.tcx,
|
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
borrow_spans.args_subdiag(&mut err, |args_span| {
|
borrow_spans.args_subdiag(&mut err, |args_span| {
|
||||||
crate::session_diagnostics::CaptureArgLabel::Capture {
|
crate::session_diagnostics::CaptureArgLabel::Capture {
|
||||||
|
@ -3808,15 +3758,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic(
|
self.explain_why_borrow_contains_point(location, loan, None)
|
||||||
self.infcx.tcx,
|
.add_explanation_to_diagnostic(&self, &mut err, "", None, None);
|
||||||
self.body,
|
|
||||||
&self.local_names,
|
|
||||||
&mut err,
|
|
||||||
"",
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.explain_deref_coercion(loan, &mut err);
|
self.explain_deref_coercion(loan, &mut err);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::assert_matches::assert_matches;
|
||||||
use rustc_errors::{Applicability, Diag};
|
use rustc_errors::{Applicability, Diag};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_index::IndexSlice;
|
|
||||||
use rustc_infer::infer::NllRegionVariableOrigin;
|
use rustc_infer::infer::NllRegionVariableOrigin;
|
||||||
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
|
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
|
@ -18,14 +17,15 @@ use rustc_middle::mir::{
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
||||||
use rustc_middle::util::CallKind;
|
use rustc_middle::util::CallKind;
|
||||||
use rustc_span::{DesugaringKind, Span, Symbol, kw, sym};
|
use rustc_span::{DesugaringKind, Span, kw, sym};
|
||||||
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use super::{RegionName, UseSpans, find_use};
|
use super::{RegionName, UseSpans, find_use};
|
||||||
use crate::borrow_set::BorrowData;
|
use crate::borrow_set::BorrowData;
|
||||||
|
use crate::constraints::OutlivesConstraint;
|
||||||
use crate::nll::ConstraintDescription;
|
use crate::nll::ConstraintDescription;
|
||||||
use crate::region_infer::{BlameConstraint, Cause, ExtraConstraintInfo};
|
use crate::region_infer::{BlameConstraint, Cause};
|
||||||
use crate::{MirBorrowckCtxt, WriteKind};
|
use crate::{MirBorrowckCtxt, WriteKind};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -43,7 +43,7 @@ pub(crate) enum BorrowExplanation<'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
region_name: RegionName,
|
region_name: RegionName,
|
||||||
opt_place_desc: Option<String>,
|
opt_place_desc: Option<String>,
|
||||||
extra_info: Vec<ExtraConstraintInfo>,
|
path: Vec<OutlivesConstraint<'tcx>>,
|
||||||
},
|
},
|
||||||
Unexplained,
|
Unexplained,
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,16 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
}
|
}
|
||||||
pub(crate) fn add_explanation_to_diagnostic(
|
pub(crate) fn add_explanation_to_diagnostic(
|
||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'tcx>,
|
cx: &MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
|
||||||
local_names: &IndexSlice<Local, Option<Symbol>>,
|
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
borrow_desc: &str,
|
borrow_desc: &str,
|
||||||
borrow_span: Option<Span>,
|
borrow_span: Option<Span>,
|
||||||
multiple_borrow_span: Option<(Span, Span)>,
|
multiple_borrow_span: Option<(Span, Span)>,
|
||||||
) {
|
) {
|
||||||
|
let tcx = cx.infcx.tcx;
|
||||||
|
let body = cx.body;
|
||||||
|
let local_names = &cx.local_names;
|
||||||
|
|
||||||
if let Some(span) = borrow_span {
|
if let Some(span) = borrow_span {
|
||||||
let def_id = body.source.def_id();
|
let def_id = body.source.def_id();
|
||||||
if let Some(node) = tcx.hir().get_if_local(def_id)
|
if let Some(node) = tcx.hir().get_if_local(def_id)
|
||||||
|
@ -306,7 +308,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
ref region_name,
|
ref region_name,
|
||||||
ref opt_place_desc,
|
ref opt_place_desc,
|
||||||
from_closure: _,
|
from_closure: _,
|
||||||
ref extra_info,
|
ref path,
|
||||||
} => {
|
} => {
|
||||||
region_name.highlight_region_name(err);
|
region_name.highlight_region_name(err);
|
||||||
|
|
||||||
|
@ -328,13 +330,8 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
for extra in extra_info {
|
cx.add_placeholder_from_predicate_note(err, &path);
|
||||||
match extra {
|
cx.add_sized_or_copy_bound_info(err, category, &path);
|
||||||
ExtraConstraintInfo::PlaceholderFromPredicate(span) => {
|
|
||||||
err.span_note(*span, "due to current limitations in the borrow checker, this implies a `'static` lifetime");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let ConstraintCategory::Cast {
|
if let ConstraintCategory::Cast {
|
||||||
is_implicit_coercion: true,
|
is_implicit_coercion: true,
|
||||||
|
@ -487,8 +484,9 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
borrow_region: RegionVid,
|
borrow_region: RegionVid,
|
||||||
outlived_region: RegionVid,
|
outlived_region: RegionVid,
|
||||||
) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) {
|
) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<OutlivesConstraint<'tcx>>)
|
||||||
let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint(
|
{
|
||||||
|
let (blame_constraint, path) = self.regioncx.best_blame_constraint(
|
||||||
borrow_region,
|
borrow_region,
|
||||||
NllRegionVariableOrigin::FreeRegion,
|
NllRegionVariableOrigin::FreeRegion,
|
||||||
|r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region),
|
|r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region),
|
||||||
|
@ -497,7 +495,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
|
|
||||||
let outlived_fr_name = self.give_region_a_name(outlived_region);
|
let outlived_fr_name = self.give_region_a_name(outlived_region);
|
||||||
|
|
||||||
(category, from_closure, cause.span, outlived_fr_name, extra_info)
|
(category, from_closure, cause.span, outlived_fr_name, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns structured explanation for *why* the borrow contains the
|
/// Returns structured explanation for *why* the borrow contains the
|
||||||
|
@ -596,7 +594,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
|
|
||||||
None => {
|
None => {
|
||||||
if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
|
if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
|
||||||
let (category, from_closure, span, region_name, extra_info) =
|
let (category, from_closure, span, region_name, path) =
|
||||||
self.free_region_constraint_info(borrow_region_vid, region);
|
self.free_region_constraint_info(borrow_region_vid, region);
|
||||||
if let Some(region_name) = region_name {
|
if let Some(region_name) = region_name {
|
||||||
let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
|
let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref());
|
||||||
|
@ -606,7 +604,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||||
span,
|
span,
|
||||||
region_name,
|
region_name,
|
||||||
opt_place_desc,
|
opt_place_desc,
|
||||||
extra_info,
|
path,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("Could not generate a region name");
|
debug!("Could not generate a region name");
|
||||||
|
|
|
@ -8,14 +8,16 @@ use rustc_errors::{Applicability, Diag, MultiSpan};
|
||||||
use rustc_hir::def::{CtorKind, Namespace};
|
use rustc_hir::def::{CtorKind, Namespace};
|
||||||
use rustc_hir::{self as hir, CoroutineKind, LangItem};
|
use rustc_hir::{self as hir, CoroutineKind, LangItem};
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_infer::infer::BoundRegionConversionTime;
|
use rustc_infer::infer::{
|
||||||
|
BoundRegionConversionTime, NllRegionVariableOrigin, RegionVariableOrigin,
|
||||||
|
};
|
||||||
use rustc_infer::traits::SelectionError;
|
use rustc_infer::traits::SelectionError;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::tcx::PlaceTy;
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
AggregateKind, CallSource, ConstOperand, FakeReadCause, Local, LocalInfo, LocalKind, Location,
|
AggregateKind, CallSource, ConstOperand, ConstraintCategory, FakeReadCause, Local, LocalInfo,
|
||||||
Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
|
LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement,
|
||||||
TerminatorKind,
|
StatementKind, Terminator, TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::print::Print;
|
use rustc_middle::ty::print::Print;
|
||||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||||
|
@ -33,7 +35,9 @@ use tracing::debug;
|
||||||
|
|
||||||
use super::MirBorrowckCtxt;
|
use super::MirBorrowckCtxt;
|
||||||
use super::borrow_set::BorrowData;
|
use super::borrow_set::BorrowData;
|
||||||
|
use crate::constraints::OutlivesConstraint;
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
|
use crate::nll::ConstraintDescription;
|
||||||
use crate::session_diagnostics::{
|
use crate::session_diagnostics::{
|
||||||
CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
|
CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
|
||||||
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
|
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
|
||||||
|
@ -619,6 +623,52 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
region.print(&mut printer).unwrap();
|
region.print(&mut printer).unwrap();
|
||||||
printer.into_buffer()
|
printer.into_buffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a note to region errors and borrow explanations when higher-ranked regions in predicates
|
||||||
|
/// implicitly introduce an "outlives `'static`" constraint.
|
||||||
|
fn add_placeholder_from_predicate_note(
|
||||||
|
&self,
|
||||||
|
err: &mut Diag<'_>,
|
||||||
|
path: &[OutlivesConstraint<'tcx>],
|
||||||
|
) {
|
||||||
|
let predicate_span = path.iter().find_map(|constraint| {
|
||||||
|
let outlived = constraint.sub;
|
||||||
|
if let Some(origin) = self.regioncx.var_infos.get(outlived)
|
||||||
|
&& let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(_)) =
|
||||||
|
origin.origin
|
||||||
|
&& let ConstraintCategory::Predicate(span) = constraint.category
|
||||||
|
{
|
||||||
|
Some(span)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(span) = predicate_span {
|
||||||
|
err.span_note(span, "due to current limitations in the borrow checker, this implies a `'static` lifetime");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a label to region errors and borrow explanations when outlives constraints arise from
|
||||||
|
/// proving a type implements `Sized` or `Copy`.
|
||||||
|
fn add_sized_or_copy_bound_info(
|
||||||
|
&self,
|
||||||
|
err: &mut Diag<'_>,
|
||||||
|
blamed_category: ConstraintCategory<'tcx>,
|
||||||
|
path: &[OutlivesConstraint<'tcx>],
|
||||||
|
) {
|
||||||
|
for sought_category in [ConstraintCategory::SizedBound, ConstraintCategory::CopyBound] {
|
||||||
|
if sought_category != blamed_category
|
||||||
|
&& let Some(sought_constraint) = path.iter().find(|c| c.category == sought_category)
|
||||||
|
{
|
||||||
|
let label = format!(
|
||||||
|
"requirement occurs due to {}",
|
||||||
|
sought_category.description().trim_end()
|
||||||
|
);
|
||||||
|
err.span_label(sought_constraint.span, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The span(s) associated to a use of a place.
|
/// The span(s) associated to a use of a place.
|
||||||
|
|
|
@ -13,7 +13,7 @@ use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate};
|
||||||
use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
|
use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::hir::place::PlaceBase;
|
use rustc_middle::hir::place::PlaceBase;
|
||||||
use rustc_middle::mir::{ConstraintCategory, ReturnConstraint};
|
use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint};
|
||||||
use rustc_middle::ty::{self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeVisitor};
|
use rustc_middle::ty::{self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeVisitor};
|
||||||
use rustc_span::{Ident, Span, kw};
|
use rustc_span::{Ident, Span, kw};
|
||||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||||
|
@ -29,7 +29,7 @@ use tracing::{debug, instrument, trace};
|
||||||
use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource};
|
use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource};
|
||||||
use crate::nll::ConstraintDescription;
|
use crate::nll::ConstraintDescription;
|
||||||
use crate::region_infer::values::RegionElement;
|
use crate::region_infer::values::RegionElement;
|
||||||
use crate::region_infer::{BlameConstraint, ExtraConstraintInfo, TypeTest};
|
use crate::region_infer::{BlameConstraint, TypeTest};
|
||||||
use crate::session_diagnostics::{
|
use crate::session_diagnostics::{
|
||||||
FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr,
|
FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr,
|
||||||
LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
|
LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
|
||||||
|
@ -49,8 +49,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
|
||||||
ConstraintCategory::Cast { is_implicit_coercion: false, .. } => "cast ",
|
ConstraintCategory::Cast { is_implicit_coercion: false, .. } => "cast ",
|
||||||
ConstraintCategory::Cast { is_implicit_coercion: true, .. } => "coercion ",
|
ConstraintCategory::Cast { is_implicit_coercion: true, .. } => "coercion ",
|
||||||
ConstraintCategory::CallArgument(_) => "argument ",
|
ConstraintCategory::CallArgument(_) => "argument ",
|
||||||
ConstraintCategory::TypeAnnotation => "type annotation ",
|
ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg) => "generic argument ",
|
||||||
ConstraintCategory::ClosureBounds => "closure body ",
|
ConstraintCategory::TypeAnnotation(_) => "type annotation ",
|
||||||
ConstraintCategory::SizedBound => "proving this value is `Sized` ",
|
ConstraintCategory::SizedBound => "proving this value is `Sized` ",
|
||||||
ConstraintCategory::CopyBound => "copying this value ",
|
ConstraintCategory::CopyBound => "copying this value ",
|
||||||
ConstraintCategory::OpaqueType => "opaque type ",
|
ConstraintCategory::OpaqueType => "opaque type ",
|
||||||
|
@ -440,8 +440,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
) {
|
) {
|
||||||
debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
|
debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
|
||||||
|
|
||||||
let (blame_constraint, extra_info) =
|
let (blame_constraint, path) = self.regioncx.best_blame_constraint(fr, fr_origin, |r| {
|
||||||
self.regioncx.best_blame_constraint(fr, fr_origin, |r| {
|
|
||||||
self.regioncx.provides_universal_region(r, fr, outlived_fr)
|
self.regioncx.provides_universal_region(r, fr, outlived_fr)
|
||||||
});
|
});
|
||||||
let BlameConstraint { category, cause, variance_info, .. } = blame_constraint;
|
let BlameConstraint { category, cause, variance_info, .. } = blame_constraint;
|
||||||
|
@ -554,13 +553,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for extra in extra_info {
|
self.add_placeholder_from_predicate_note(&mut diag, &path);
|
||||||
match extra {
|
self.add_sized_or_copy_bound_info(&mut diag, category, &path);
|
||||||
ExtraConstraintInfo::PlaceholderFromPredicate(span) => {
|
|
||||||
diag.span_note(span, "due to current limitations in the borrow checker, this implies a `'static` lifetime");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.buffer_error(diag);
|
self.buffer_error(diag);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#![feature(assert_matches)]
|
#![feature(assert_matches)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(file_buffered)]
|
#![feature(file_buffered)]
|
||||||
|
#![feature(if_let_guard)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
|
@ -13,15 +13,16 @@ use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound,
|
||||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
|
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
BasicBlock, Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy,
|
AnnotationSource, BasicBlock, Body, ClosureOutlivesRequirement, ClosureOutlivesSubject,
|
||||||
ClosureRegionRequirements, ConstraintCategory, Local, Location, ReturnConstraint,
|
ClosureOutlivesSubjectTy, ClosureRegionRequirements, ConstraintCategory, Local, Location,
|
||||||
TerminatorKind,
|
ReturnConstraint, TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_middle::ty::fold::fold_regions;
|
use rustc_middle::ty::fold::fold_regions;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex};
|
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex};
|
||||||
use rustc_mir_dataflow::points::DenseLocationMap;
|
use rustc_mir_dataflow::points::DenseLocationMap;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
use rustc_span::hygiene::DesugaringKind;
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
use crate::BorrowckInferCtxt;
|
use crate::BorrowckInferCtxt;
|
||||||
|
@ -315,11 +316,6 @@ enum Trace<'tcx> {
|
||||||
NotVisited,
|
NotVisited,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
||||||
pub(crate) enum ExtraConstraintInfo {
|
|
||||||
PlaceholderFromPredicate(Span),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(infcx, sccs), level = "debug")]
|
#[instrument(skip(infcx, sccs), level = "debug")]
|
||||||
fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
|
fn sccs_info<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, sccs: &ConstraintSccs) {
|
||||||
use crate::renumber::RegionCtxt;
|
use crate::renumber::RegionCtxt;
|
||||||
|
@ -1938,7 +1934,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
from_region: RegionVid,
|
from_region: RegionVid,
|
||||||
from_region_origin: NllRegionVariableOrigin,
|
from_region_origin: NllRegionVariableOrigin,
|
||||||
target_test: impl Fn(RegionVid) -> bool,
|
target_test: impl Fn(RegionVid) -> bool,
|
||||||
) -> (BlameConstraint<'tcx>, Vec<ExtraConstraintInfo>) {
|
) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) {
|
||||||
// Find all paths
|
// Find all paths
|
||||||
let (path, target_region) = self
|
let (path, target_region) = self
|
||||||
.find_constraint_paths_between_regions(from_region, target_test)
|
.find_constraint_paths_between_regions(from_region, target_test)
|
||||||
|
@ -1960,25 +1956,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut extra_info = vec![];
|
|
||||||
for constraint in path.iter() {
|
|
||||||
let outlived = constraint.sub;
|
|
||||||
let Some(origin) = self.var_infos.get(outlived) else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(p)) = origin.origin
|
|
||||||
else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
debug!(?constraint, ?p);
|
|
||||||
let ConstraintCategory::Predicate(span) = constraint.category else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
extra_info.push(ExtraConstraintInfo::PlaceholderFromPredicate(span));
|
|
||||||
// We only want to point to one
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint.
|
// We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint.
|
||||||
// Instead, we use it to produce an improved `ObligationCauseCode`.
|
// Instead, we use it to produce an improved `ObligationCauseCode`.
|
||||||
// FIXME - determine what we should do if we encounter multiple
|
// FIXME - determine what we should do if we encounter multiple
|
||||||
|
@ -1997,42 +1974,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| ObligationCauseCode::Misc);
|
.unwrap_or_else(|| ObligationCauseCode::Misc);
|
||||||
|
|
||||||
// Classify each of the constraints along the path.
|
// When reporting an error, there is typically a chain of constraints leading from some
|
||||||
let mut categorized_path: Vec<BlameConstraint<'tcx>> = path
|
// "source" region which must outlive some "target" region.
|
||||||
.iter()
|
|
||||||
.map(|constraint| BlameConstraint {
|
|
||||||
category: constraint.category,
|
|
||||||
from_closure: constraint.from_closure,
|
|
||||||
cause: ObligationCause::new(constraint.span, CRATE_DEF_ID, cause_code.clone()),
|
|
||||||
variance_info: constraint.variance_info,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
debug!("categorized_path={:#?}", categorized_path);
|
|
||||||
|
|
||||||
// To find the best span to cite, we first try to look for the
|
|
||||||
// final constraint that is interesting and where the `sup` is
|
|
||||||
// not unified with the ultimate target region. The reason
|
|
||||||
// for this is that we have a chain of constraints that lead
|
|
||||||
// from the source to the target region, something like:
|
|
||||||
//
|
|
||||||
// '0: '1 ('0 is the source)
|
|
||||||
// '1: '2
|
|
||||||
// '2: '3
|
|
||||||
// '3: '4
|
|
||||||
// '4: '5
|
|
||||||
// '5: '6 ('6 is the target)
|
|
||||||
//
|
|
||||||
// Some of those regions are unified with `'6` (in the same
|
|
||||||
// SCC). We want to screen those out. After that point, the
|
|
||||||
// "closest" constraint we have to the end is going to be the
|
|
||||||
// most likely to be the point where the value escapes -- but
|
|
||||||
// we still want to screen for an "interesting" point to
|
|
||||||
// highlight (e.g., a call site or something).
|
|
||||||
let target_scc = self.constraint_sccs.scc(target_region);
|
|
||||||
let mut range = 0..path.len();
|
|
||||||
|
|
||||||
// As noted above, when reporting an error, there is typically a chain of constraints
|
|
||||||
// leading from some "source" region which must outlive some "target" region.
|
|
||||||
// In most cases, we prefer to "blame" the constraints closer to the target --
|
// In most cases, we prefer to "blame" the constraints closer to the target --
|
||||||
// but there is one exception. When constraints arise from higher-ranked subtyping,
|
// but there is one exception. When constraints arise from higher-ranked subtyping,
|
||||||
// we generally prefer to blame the source value,
|
// we generally prefer to blame the source value,
|
||||||
|
@ -2073,78 +2016,114 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
|
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let find_region = |i: &usize| {
|
// To pick a constraint to blame, we organize constraints by how interesting we expect them
|
||||||
let constraint = &path[*i];
|
// to be in diagnostics, then pick the most interesting one closest to either the source or
|
||||||
|
// the target on our constraint path.
|
||||||
let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup);
|
let constraint_interest = |constraint: &OutlivesConstraint<'tcx>| {
|
||||||
|
// Try to avoid blaming constraints from desugarings, since they may not clearly match
|
||||||
if blame_source {
|
// match what users have written. As an exception, allow blaming returns generated by
|
||||||
match categorized_path[*i].category {
|
// `?` desugaring, since the correspondence is fairly clear.
|
||||||
ConstraintCategory::OpaqueType
|
let category = if let Some(kind) = constraint.span.desugaring_kind()
|
||||||
| ConstraintCategory::Boring
|
&& (kind != DesugaringKind::QuestionMark
|
||||||
| ConstraintCategory::BoringNoLocation
|
|| !matches!(constraint.category, ConstraintCategory::Return(_)))
|
||||||
| ConstraintCategory::Internal
|
{
|
||||||
| ConstraintCategory::Predicate(_) => false,
|
ConstraintCategory::Boring
|
||||||
ConstraintCategory::TypeAnnotation
|
|
||||||
| ConstraintCategory::Return(_)
|
|
||||||
| ConstraintCategory::Yield => true,
|
|
||||||
_ => constraint_sup_scc != target_scc,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
!matches!(
|
constraint.category
|
||||||
categorized_path[*i].category,
|
};
|
||||||
ConstraintCategory::OpaqueType
|
|
||||||
| ConstraintCategory::Boring
|
match category {
|
||||||
| ConstraintCategory::BoringNoLocation
|
// Returns usually provide a type to blame and have specially written diagnostics,
|
||||||
| ConstraintCategory::Internal
|
// so prioritize them.
|
||||||
| ConstraintCategory::Predicate(_)
|
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(
|
||||||
|
AnnotationSource::Ascription
|
||||||
|
| AnnotationSource::Declaration
|
||||||
|
| AnnotationSource::OpaqueCast,
|
||||||
)
|
)
|
||||||
|
| ConstraintCategory::Cast { .. }
|
||||||
|
| ConstraintCategory::CallArgument(_)
|
||||||
|
| ConstraintCategory::CopyBound
|
||||||
|
| ConstraintCategory::SizedBound
|
||||||
|
| ConstraintCategory::Assignment
|
||||||
|
| ConstraintCategory::Usage
|
||||||
|
| ConstraintCategory::ClosureUpvar(_) => 2,
|
||||||
|
// Generic arguments are unlikely to be what relates regions together
|
||||||
|
ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg) => 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 =
|
let best_choice = if blame_source {
|
||||||
if blame_source { range.rev().find(find_region) } else { range.find(find_region) };
|
path.iter().enumerate().rev().min_by_key(|(_, c)| constraint_interest(c)).unwrap().0
|
||||||
|
} else {
|
||||||
|
path.iter().enumerate().min_by_key(|(_, c)| constraint_interest(c)).unwrap().0
|
||||||
|
};
|
||||||
|
|
||||||
debug!(?best_choice, ?blame_source, ?extra_info);
|
debug!(?best_choice, ?blame_source);
|
||||||
|
|
||||||
if let Some(i) = best_choice {
|
let best_constraint = if let Some(next) = path.get(best_choice + 1)
|
||||||
if let Some(next) = categorized_path.get(i + 1) {
|
&& matches!(path[best_choice].category, ConstraintCategory::Return(_))
|
||||||
if matches!(categorized_path[i].category, ConstraintCategory::Return(_))
|
|
||||||
&& next.category == ConstraintCategory::OpaqueType
|
&& 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.
|
||||||
return (next.clone(), extra_info);
|
*next
|
||||||
}
|
} else if path[best_choice].category == ConstraintCategory::Return(ReturnConstraint::Normal)
|
||||||
}
|
&& let Some(field) = path.iter().find_map(|p| {
|
||||||
|
if let ConstraintCategory::ClosureUpvar(f) = p.category { Some(f) } else { None }
|
||||||
if categorized_path[i].category == ConstraintCategory::Return(ReturnConstraint::Normal)
|
})
|
||||||
{
|
{
|
||||||
let field = categorized_path.iter().find_map(|p| {
|
OutlivesConstraint {
|
||||||
if let ConstraintCategory::ClosureUpvar(f) = p.category {
|
category: ConstraintCategory::Return(ReturnConstraint::ClosureUpvar(field)),
|
||||||
Some(f)
|
..path[best_choice]
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
path[best_choice]
|
||||||
}
|
};
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(field) = field {
|
let blame_constraint = BlameConstraint {
|
||||||
categorized_path[i].category =
|
category: best_constraint.category,
|
||||||
ConstraintCategory::Return(ReturnConstraint::ClosureUpvar(field));
|
from_closure: best_constraint.from_closure,
|
||||||
}
|
cause: ObligationCause::new(best_constraint.span, CRATE_DEF_ID, cause_code.clone()),
|
||||||
}
|
variance_info: best_constraint.variance_info,
|
||||||
|
};
|
||||||
return (categorized_path[i].clone(), extra_info);
|
(blame_constraint, path)
|
||||||
}
|
|
||||||
|
|
||||||
// If that search fails, that is.. unusual. Maybe everything
|
|
||||||
// is in the same SCC or something. In that case, find what
|
|
||||||
// appears to be the most interesting point to report to the
|
|
||||||
// user via an even more ad-hoc guess.
|
|
||||||
categorized_path.sort_by_key(|p| p.category);
|
|
||||||
debug!("sorted_path={:#?}", categorized_path);
|
|
||||||
|
|
||||||
(categorized_path.remove(0), extra_info)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
|
||||||
|
|
|
@ -298,7 +298,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
context.ambient_variance(),
|
context.ambient_variance(),
|
||||||
base_ty.ty,
|
base_ty.ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::TypeAnnotation,
|
ConstraintCategory::TypeAnnotation(AnnotationSource::OpaqueCast),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
ty::Invariant,
|
ty::Invariant,
|
||||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||||
locations,
|
locations,
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg),
|
||||||
) {
|
) {
|
||||||
let annotation = &self.typeck.user_type_annotations[annotation_index];
|
let annotation = &self.typeck.user_type_annotations[annotation_index];
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
|
@ -455,7 +455,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
ty::Invariant,
|
ty::Invariant,
|
||||||
user_ty,
|
user_ty,
|
||||||
Locations::All(*span),
|
Locations::All(*span),
|
||||||
ConstraintCategory::TypeAnnotation,
|
ConstraintCategory::TypeAnnotation(AnnotationSource::Declaration),
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
|
@ -892,6 +892,19 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
Some(l) if !body.local_decls[l].is_user_variable() => {
|
Some(l) if !body.local_decls[l].is_user_variable() => {
|
||||||
ConstraintCategory::Boring
|
ConstraintCategory::Boring
|
||||||
}
|
}
|
||||||
|
Some(_)
|
||||||
|
if let Some(body_id) = tcx
|
||||||
|
.hir_node_by_def_id(body.source.def_id().expect_local())
|
||||||
|
.body_id()
|
||||||
|
&& let params = tcx.hir().body(body_id).params
|
||||||
|
&& params
|
||||||
|
.iter()
|
||||||
|
.any(|param| param.span.contains(stmt.source_info.span)) =>
|
||||||
|
{
|
||||||
|
// Assignments generated from lowering argument patterns shouldn't be called
|
||||||
|
// "assignments" in diagnostics and aren't interesting to blame for errors.
|
||||||
|
ConstraintCategory::Boring
|
||||||
|
}
|
||||||
_ => ConstraintCategory::Assignment,
|
_ => ConstraintCategory::Assignment,
|
||||||
};
|
};
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -927,7 +940,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
ty::Invariant,
|
ty::Invariant,
|
||||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg),
|
||||||
) {
|
) {
|
||||||
let annotation = &self.user_type_annotations[annotation_index];
|
let annotation = &self.user_type_annotations[annotation_index];
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
|
@ -962,7 +975,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
*variance,
|
*variance,
|
||||||
projection,
|
projection,
|
||||||
Locations::All(stmt.source_info.span),
|
Locations::All(stmt.source_info.span),
|
||||||
ConstraintCategory::TypeAnnotation,
|
ConstraintCategory::TypeAnnotation(AnnotationSource::Ascription),
|
||||||
) {
|
) {
|
||||||
let annotation = &self.user_type_annotations[projection.base];
|
let annotation = &self.user_type_annotations[projection.base];
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
|
@ -1226,6 +1239,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
Some(l) if !body.local_decls[l].is_user_variable() => {
|
Some(l) if !body.local_decls[l].is_user_variable() => {
|
||||||
ConstraintCategory::Boring
|
ConstraintCategory::Boring
|
||||||
}
|
}
|
||||||
|
// The return type of a call is interesting for diagnostics.
|
||||||
_ => ConstraintCategory::Assignment,
|
_ => ConstraintCategory::Assignment,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2169,7 +2183,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
ty_left,
|
ty_left,
|
||||||
common_ty,
|
common_ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::CallArgument(None),
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
|
bug!("Could not equate type variable with {:?}: {:?}", ty_left, err)
|
||||||
|
@ -2178,7 +2192,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
ty_right,
|
ty_right,
|
||||||
common_ty,
|
common_ty,
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::CallArgument(None),
|
||||||
) {
|
) {
|
||||||
span_mirbug!(
|
span_mirbug!(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -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,29 +224,22 @@ 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,
|
||||||
UseAsConst,
|
UseAsConst,
|
||||||
UseAsStatic,
|
UseAsStatic,
|
||||||
TypeAnnotation,
|
TypeAnnotation(AnnotationSource),
|
||||||
Cast {
|
Cast {
|
||||||
/// Whether this cast is a coercion that was automatically inserted by the compiler.
|
/// Whether this cast is a coercion that was automatically inserted by the compiler.
|
||||||
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>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A constraint that came from checking the body of a closure.
|
|
||||||
///
|
|
||||||
/// We try to get the category that the closure used when reporting this.
|
|
||||||
ClosureBounds,
|
|
||||||
|
|
||||||
/// 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,13 +268,22 @@ 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,
|
||||||
ClosureUpvar(FieldIdx),
|
ClosureUpvar(FieldIdx),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
||||||
|
pub enum AnnotationSource {
|
||||||
|
Ascription,
|
||||||
|
Declaration,
|
||||||
|
OpaqueCast,
|
||||||
|
GenericArg,
|
||||||
|
}
|
||||||
|
|
||||||
/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
|
/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
|
||||||
/// that must outlive some region.
|
/// that must outlive some region.
|
||||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
|
|
|
@ -6,24 +6,24 @@ LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | let z: I::A = if cond { x } else { y };
|
|
||||||
| ^ assignment requires that `'a` must outlive `'b`
|
|
||||||
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
|
||||||
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:40
|
|
||||||
|
|
|
||||||
LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
|
|
||||||
| -- -- lifetime `'b` defined here
|
|
||||||
| |
|
|
||||||
| lifetime `'a` defined here
|
|
||||||
...
|
|
||||||
LL | let z: I::A = if cond { x } else { y };
|
LL | let z: I::A = if cond { x } else { y };
|
||||||
| ^ assignment requires that `'b` must outlive `'a`
|
| ^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:40
|
||||||
|
|
|
||||||
|
LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
|
||||||
|
| -- -- lifetime `'b` defined here
|
||||||
|
| |
|
||||||
|
| lifetime `'a` defined here
|
||||||
|
...
|
||||||
|
LL | let z: I::A = if cond { x } else { y };
|
||||||
|
| ^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
||||||
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
|
|
||||||
help: `'a` and `'b` must be the same: replace one with the other
|
help: `'a` and `'b` must be the same: replace one with the other
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
|
@ -7,9 +7,9 @@ LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
|
LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
|
||||||
LL | let a = bar(f, x);
|
LL | let a = bar(f, x);
|
||||||
| ^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
| ^^^^^^^^^ argument 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 the type `Type<'_>`, which makes the generic argument `'_` invariant
|
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
|
||||||
= note: the struct `Type<'a>` is invariant over the parameter `'a`
|
= note: the struct `Type<'a>` is invariant over the parameter `'a`
|
||||||
= 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
|
||||||
|
@ -23,9 +23,9 @@ LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | let b = bar(f, y);
|
LL | let b = bar(f, y);
|
||||||
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^ argument 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 the type `Type<'_>`, which makes the generic argument `'_` invariant
|
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
|
||||||
= note: the struct `Type<'a>` is invariant over the parameter `'a`
|
= note: the struct `Type<'a>` is invariant over the parameter `'a`
|
||||||
= 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
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | let c = async || { println!("{}", *x); };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ------------ argument requires that `x` is borrowed for `'a`
|
| ---------------------------- argument requires that `x` is borrowed for `'a`
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
@ -21,9 +21,9 @@ LL | fn simple<'a>(x: &'a i32) {
|
||||||
LL | let c = async move || { println!("{}", *x); };
|
LL | let c = async move || { println!("{}", *x); };
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
| ^--
|
| ---------------^---
|
||||||
| |
|
| | |
|
||||||
| borrowed value does not live long enough
|
| | borrowed value does not live long enough
|
||||||
| argument requires that `c` is borrowed for `'a`
|
| argument requires that `c` is borrowed for `'a`
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
LL | }
|
LL | }
|
||||||
|
@ -38,7 +38,7 @@ LL | let c = async || { println!("{}", *x.0); };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ------------ argument requires that `x` is borrowed for `'a`
|
| ---------------------------- argument requires that `x` is borrowed for `'a`
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
@ -52,7 +52,7 @@ LL | let c = async || { println!("{}", *x.0); };
|
||||||
| ---------------------------------- borrow of `x` occurs here
|
| ---------------------------------- borrow of `x` occurs here
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ------------ argument requires that `x` is borrowed for `'a`
|
| ---------------------------- argument requires that `x` is borrowed for `'a`
|
||||||
LL |
|
LL |
|
||||||
LL | let c = async move || { println!("{}", *x.0); };
|
LL | let c = async move || { println!("{}", *x.0); };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `x` occurs here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `x` occurs here
|
||||||
|
@ -66,9 +66,9 @@ LL | fn through_field<'a>(x: S<'a>) {
|
||||||
LL | let c = async move || { println!("{}", *x.0); };
|
LL | let c = async move || { println!("{}", *x.0); };
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
| ^--
|
| ---------------^---
|
||||||
| |
|
| | |
|
||||||
| borrowed value does not live long enough
|
| | borrowed value does not live long enough
|
||||||
| argument requires that `c` is borrowed for `'a`
|
| argument requires that `c` is borrowed for `'a`
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
LL | }
|
LL | }
|
||||||
|
@ -83,9 +83,9 @@ LL | fn through_field<'a>(x: S<'a>) {
|
||||||
LL | let c = async move || { println!("{}", *x.0); };
|
LL | let c = async move || { println!("{}", *x.0); };
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
| ---
|
| -------------------
|
||||||
| |
|
| | |
|
||||||
| borrow of `c` occurs here
|
| | borrow of `c` occurs here
|
||||||
| argument requires that `c` is borrowed for `'a`
|
| argument requires that `c` is borrowed for `'a`
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ^ move out of `c` occurs here
|
| ^ move out of `c` occurs here
|
||||||
|
@ -99,18 +99,18 @@ LL | let c = async || { println!("{}", *x.0); };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ------------ argument requires that `x` is borrowed for `'a`
|
| ---------------------------- argument requires that `x` is borrowed for `'a`
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0621]: explicit lifetime required in the type of `x`
|
error[E0621]: explicit lifetime required in the type of `x`
|
||||||
--> $DIR/without-precise-captures-we-are-powerless.rs:38:20
|
--> $DIR/without-precise-captures-we-are-powerless.rs:38:5
|
||||||
|
|
|
|
||||||
LL | fn through_field_and_ref<'a>(x: &S<'a>) {
|
LL | fn through_field_and_ref<'a>(x: &S<'a>) {
|
||||||
| ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
|
| ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
|
||||||
...
|
...
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ^^^^^^^^^^^^ lifetime `'a` required
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
|
||||||
|
|
||||||
error[E0597]: `c` does not live long enough
|
error[E0597]: `c` does not live long enough
|
||||||
--> $DIR/without-precise-captures-we-are-powerless.rs:43:20
|
--> $DIR/without-precise-captures-we-are-powerless.rs:43:20
|
||||||
|
@ -120,22 +120,22 @@ LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
|
||||||
LL | let c = async move || { println!("{}", *x.0); };
|
LL | let c = async move || { println!("{}", *x.0); };
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | outlives::<'a>(c());
|
LL | outlives::<'a>(c());
|
||||||
| ^--
|
| ---------------^---
|
||||||
| |
|
| | |
|
||||||
| borrowed value does not live long enough
|
| | borrowed value does not live long enough
|
||||||
| argument requires that `c` is borrowed for `'a`
|
| argument requires that `c` is borrowed for `'a`
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
error[E0621]: explicit lifetime required in the type of `x`
|
error[E0621]: explicit lifetime required in the type of `x`
|
||||||
--> $DIR/without-precise-captures-we-are-powerless.rs:44:20
|
--> $DIR/without-precise-captures-we-are-powerless.rs:44:5
|
||||||
|
|
|
|
||||||
LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
|
LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
|
||||||
| ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
|
| ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
|
||||||
...
|
...
|
||||||
LL | outlives::<'a>(call_once(c));
|
LL | outlives::<'a>(call_once(c));
|
||||||
| ^^^^^^^^^^^^ lifetime `'a` required
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
|
||||||
|
|
||||||
error: aborting due to 10 previous errors
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ impl Xyz {
|
||||||
&'a self, foo: &dyn Foo
|
&'a self, foo: &dyn Foo
|
||||||
) -> &dyn Foo //~ WARNING elided lifetime has a name
|
) -> &dyn Foo //~ WARNING elided lifetime has a name
|
||||||
{
|
{
|
||||||
//~^ ERROR explicit lifetime required in the type of `foo` [E0621]
|
|
||||||
foo
|
foo
|
||||||
|
//~^ ERROR explicit lifetime required in the type of `foo` [E0621]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,13 @@ LL | ) -> &dyn Foo
|
||||||
= note: `#[warn(elided_named_lifetimes)]` on by default
|
= note: `#[warn(elided_named_lifetimes)]` on by default
|
||||||
|
|
||||||
error[E0621]: explicit lifetime required in the type of `foo`
|
error[E0621]: explicit lifetime required in the type of `foo`
|
||||||
--> $DIR/issue-63388-1.rs:13:5
|
--> $DIR/issue-63388-1.rs:14:9
|
||||||
|
|
|
|
||||||
LL | &'a self, foo: &dyn Foo
|
LL | &'a self, foo: &dyn Foo
|
||||||
| -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)`
|
| -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)`
|
||||||
LL | ) -> &dyn Foo
|
...
|
||||||
LL | / {
|
LL | foo
|
||||||
LL | |
|
| ^^^ lifetime `'a` required
|
||||||
LL | | foo
|
|
||||||
LL | | }
|
|
||||||
| |_____^ lifetime `'a` required
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error; 1 warning emitted
|
error: aborting due to 1 previous error; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ impl Xyz {
|
||||||
foo: &dyn Foo, bar: &'a dyn Foo
|
foo: &dyn Foo, bar: &'a dyn Foo
|
||||||
) -> &dyn Foo //~ ERROR missing lifetime specifier
|
) -> &dyn Foo //~ ERROR missing lifetime specifier
|
||||||
{
|
{
|
||||||
//~^ ERROR explicit lifetime required in the type of `foo` [E0621]
|
|
||||||
foo
|
foo
|
||||||
|
//~^ ERROR explicit lifetime required in the type of `foo` [E0621]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,13 @@ LL | ) -> &'a dyn Foo
|
||||||
| ++
|
| ++
|
||||||
|
|
||||||
error[E0621]: explicit lifetime required in the type of `foo`
|
error[E0621]: explicit lifetime required in the type of `foo`
|
||||||
--> $DIR/issue-63388-2.rs:13:5
|
--> $DIR/issue-63388-2.rs:14:9
|
||||||
|
|
|
|
||||||
LL | foo: &dyn Foo, bar: &'a dyn Foo
|
LL | foo: &dyn Foo, bar: &'a dyn Foo
|
||||||
| -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)`
|
| -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)`
|
||||||
LL | ) -> &dyn Foo
|
...
|
||||||
LL | / {
|
LL | foo
|
||||||
LL | |
|
| ^^^ lifetime `'a` required
|
||||||
LL | | foo
|
|
||||||
LL | | }
|
|
||||||
| |_____^ lifetime `'a` required
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,12 @@ LL | extend_lt(val);
|
||||||
| argument requires that `'a` must outlive `'static`
|
| argument requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/fn-item-check-type-params.rs:39:12
|
--> $DIR/fn-item-check-type-params.rs:39:31
|
||||||
|
|
|
|
||||||
LL | pub fn test_coercion<'a>() {
|
LL | pub fn test_coercion<'a>() {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let _: fn(&'a str) -> _ = extend_lt;
|
LL | let _: fn(&'a str) -> _ = extend_lt;
|
||||||
| ^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^ coercion requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/fn-item-check-type-params.rs:48:11
|
--> $DIR/fn-item-check-type-params.rs:48:11
|
||||||
|
|
|
@ -15,7 +15,7 @@ LL | async {
|
||||||
LL | let not_static = 0;
|
LL | let not_static = 0;
|
||||||
| ---------- binding `not_static` declared here
|
| ---------- binding `not_static` declared here
|
||||||
LL | force_send(async_load(¬_static));
|
LL | force_send(async_load(¬_static));
|
||||||
| -----------^^^^^^^^^^^-
|
| ----------------------^^^^^^^^^^^--
|
||||||
| | |
|
| | |
|
||||||
| | borrowed value does not live long enough
|
| | borrowed value does not live long enough
|
||||||
| argument requires that `not_static` is borrowed for `'1`
|
| argument requires that `not_static` is borrowed for `'1`
|
||||||
|
|
|
@ -17,6 +17,8 @@ pub fn remove_package_from_database() {
|
||||||
lines_to_use.push(installed_id);
|
lines_to_use.push(installed_id);
|
||||||
//~^ ERROR borrowed data escapes outside of closure
|
//~^ ERROR borrowed data escapes outside of closure
|
||||||
//~| NOTE `installed_id` escapes the closure body here
|
//~| NOTE `installed_id` escapes the closure body here
|
||||||
|
//~| NOTE requirement occurs because of a mutable reference to `Vec<&CrateId>`
|
||||||
|
//~| NOTE mutable references are invariant over their type parameter
|
||||||
};
|
};
|
||||||
list_database(push_id);
|
list_database(push_id);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ LL | let push_id = |installed_id: &CrateId| {
|
||||||
LL |
|
LL |
|
||||||
LL | lines_to_use.push(installed_id);
|
LL | lines_to_use.push(installed_id);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&CrateId>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -71,14 +71,13 @@ error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as imm
|
||||||
LL | fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
|
LL | fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
|
LL | let reg = mk_reg();
|
||||||
|
| -------- assignment requires that `reg.sess_mut` is borrowed for `'a`
|
||||||
LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut)));
|
LL | reg.register_univ(Box::new(CapturePass::new(®.sess_mut)));
|
||||||
| ^^^^^^^^^^^^^^^^^^-----------------------------------------^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^
|
||||||
| | | |
|
| | |
|
||||||
| | | immutable borrow occurs here
|
| | immutable borrow occurs here
|
||||||
| | coercion requires that `reg.sess_mut` is borrowed for `'a`
|
|
||||||
| mutable borrow occurs here
|
| mutable borrow occurs here
|
||||||
|
|
|
||||||
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
|
||||||
|
|
||||||
error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
|
error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
|
||||||
--> $DIR/two-phase-surprise-no-conflict.rs:144:5
|
--> $DIR/two-phase-surprise-no-conflict.rs:144:5
|
||||||
|
@ -115,14 +114,13 @@ error[E0499]: cannot borrow `*reg` as mutable more than once at a time
|
||||||
LL | fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
|
LL | fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
|
LL | let reg = mk_reg();
|
||||||
|
| -------- assignment requires that `reg.sess_mut` is borrowed for `'a`
|
||||||
LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
LL | reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
|
||||||
| ^^^^^^^^^^^^^^^^^^-------------------------------------------------^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^
|
||||||
| | | |
|
| | |
|
||||||
| | | first mutable borrow occurs here
|
| | first mutable borrow occurs here
|
||||||
| | coercion requires that `reg.sess_mut` is borrowed for `'a`
|
|
||||||
| second mutable borrow occurs here
|
| second mutable borrow occurs here
|
||||||
|
|
|
||||||
= note: due to object lifetime defaults, `Box<dyn for<'b> LateLintPass<'b>>` actually means `Box<(dyn for<'b> LateLintPass<'b> + 'static)>`
|
|
||||||
|
|
||||||
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
|
||||||
--> $DIR/two-phase-surprise-no-conflict.rs:158:53
|
--> $DIR/two-phase-surprise-no-conflict.rs:158:53
|
||||||
|
|
|
@ -120,14 +120,14 @@ LL | }
|
||||||
| - `ap1` dropped here while still borrowed
|
| - `ap1` dropped here while still borrowed
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/variadic-ffi-4.rs:35:12
|
--> $DIR/variadic-ffi-4.rs:35:5
|
||||||
|
|
|
|
||||||
LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
|
LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
|
||||||
| ------- ------- has type `VaListImpl<'2>`
|
| ------- ------- has type `VaListImpl<'2>`
|
||||||
| |
|
| |
|
||||||
| has type `&mut VaListImpl<'1>`
|
| has type `&mut VaListImpl<'1>`
|
||||||
LL | *ap0 = ap1.clone();
|
LL | *ap0 = ap1.clone();
|
||||||
| ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^ assignment requires that `'2` must outlive `'1`
|
||||||
|
|
|
|
||||||
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
|
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
|
||||||
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
|
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
|
||||||
|
@ -141,7 +141,7 @@ LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut
|
||||||
| |
|
| |
|
||||||
| has type `&mut VaListImpl<'1>`
|
| has type `&mut VaListImpl<'1>`
|
||||||
LL | *ap0 = ap1.clone();
|
LL | *ap0 = ap1.clone();
|
||||||
| ^^^^^^^^^^^ argument requires that `'2` must outlive `'1`
|
| ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
|
= note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant
|
||||||
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
|
= note: the struct `VaListImpl<'f>` is invariant over the parameter `'f`
|
||||||
|
|
|
@ -42,7 +42,7 @@ fn change_assoc_1<'a, 'b>(
|
||||||
// This tests the default borrow check error, without the special casing for return values.
|
// This tests the default borrow check error, without the special casing for return values.
|
||||||
fn require_static(_: *const dyn Trait<'static>) {}
|
fn require_static(_: *const dyn Trait<'static>) {}
|
||||||
fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
||||||
require_static(ptr as _) //~ error: lifetime may not live long enough
|
require_static(ptr as _) //~ error: borrowed data escapes outside of function
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -154,14 +154,22 @@ help: `'b` and `'a` 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[E0521]: borrowed data escapes outside of function
|
||||||
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:20
|
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:5
|
||||||
|
|
|
|
||||||
LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) {
|
||||||
| -- lifetime `'a` defined here
|
| -- ---
|
||||||
|
| | |
|
||||||
|
| | `ptr` declared here, outside of the function body
|
||||||
|
| | `ptr` is a reference that is only valid in the function body
|
||||||
|
| lifetime `'a` defined here
|
||||||
LL | require_static(ptr as _)
|
LL | require_static(ptr as _)
|
||||||
| ^^^^^^^^ cast requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| `ptr` escapes the function body here
|
||||||
|
| argument requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 11 previous errors
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
Some errors have detailed explanations: E0308, E0521.
|
||||||
|
For more information about an error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -18,8 +18,8 @@ fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
|
||||||
// exploit:
|
// exploit:
|
||||||
generator.as_mut().resume("");
|
generator.as_mut().resume("");
|
||||||
generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
|
generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
|
||||||
//~^ ERROR borrowed data escapes outside of function
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
//~^ ERROR borrowed data escapes outside of function
|
||||||
thread::sleep(time::Duration::from_millis(200));
|
thread::sleep(time::Duration::from_millis(200));
|
||||||
generator.as_mut().resume(""); // <- resumes from the last `yield`, running `dbg!(ctx)`.
|
generator.as_mut().resume(""); // <- resumes from the last `yield`, running `dbg!(ctx)`.
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
error[E0521]: borrowed data escapes outside of function
|
error[E0521]: borrowed data escapes outside of function
|
||||||
--> $DIR/resume-arg-outlives-2.rs:20:5
|
--> $DIR/resume-arg-outlives-2.rs:21:5
|
||||||
|
|
|
|
||||||
LL | fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
|
LL | fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
|
||||||
| ----------- - `s` is a reference that is only valid in the function body
|
| ----------- - `s` is a reference that is only valid in the function body
|
||||||
| |
|
| |
|
||||||
| lifetime `'not_static` defined here
|
| lifetime `'not_static` defined here
|
||||||
...
|
...
|
||||||
LL | generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
|
LL | / thread::spawn(move || {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
LL | |
|
||||||
| |
|
LL | | thread::sleep(time::Duration::from_millis(200));
|
||||||
| `s` escapes the function body here
|
LL | | generator.as_mut().resume(""); // <- resumes from the last `yield`, running `dbg!(ctx)`.
|
||||||
|
LL | | })
|
||||||
|
| | ^
|
||||||
|
| | |
|
||||||
|
| |______`s` escapes the function body here
|
||||||
| argument requires that `'not_static` must outlive `'static`
|
| argument requires that `'not_static` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -46,12 +46,12 @@ 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 ()>, //~ ERROR lifetime may not live long enough
|
||||||
};
|
};
|
||||||
|
|
||||||
x(a);
|
x(a);
|
||||||
x(b); //~ ERROR lifetime may not live long enough
|
x(b);
|
||||||
x(c);
|
x(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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`
|
||||||
|
@ -133,17 +133,20 @@ LL | false => foo::<&'a ()>,
|
||||||
= 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
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/fn_def_coercion.rs:54:5
|
--> $DIR/fn_def_coercion.rs:50:18
|
||||||
|
|
|
|
||||||
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 `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | x(b);
|
LL | false => foo::<&'a ()>,
|
||||||
| ^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
|
= 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: the following changes may resolve your lifetime errors
|
help: the following changes may resolve your lifetime errors
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ LL | fn g<'a, 'b>() {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | f::<'a, 'b>(());
|
LL | f::<'a, 'b>(());
|
||||||
| ^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^ generic argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `f`
|
= note: requirement occurs because of a function pointer to `f`
|
||||||
|
|
|
@ -6,6 +6,9 @@ LL | fn foo<'a, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
|
LL | let u = v;
|
||||||
|
| - requirement occurs due to copying this value
|
||||||
|
...
|
||||||
LL | let _: &'b i32 = *u.0;
|
LL | let _: &'b i32 = *u.0;
|
||||||
| ^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
| ^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ fn needs_static() {
|
||||||
let a = display_len(&x);
|
let a = display_len(&x);
|
||||||
//~^ ERROR `x` does not live long enough
|
//~^ ERROR `x` does not live long enough
|
||||||
//~| NOTE this call may capture more lifetimes than intended
|
//~| NOTE this call may capture more lifetimes than intended
|
||||||
//~| NOTE argument requires that `x` is borrowed for `'static`
|
|
||||||
//~| NOTE borrowed value does not live long enoug
|
//~| NOTE borrowed value does not live long enoug
|
||||||
|
|
||||||
fn needs_static(_: impl Sized + 'static) {}
|
fn needs_static(_: impl Sized + 'static) {}
|
||||||
needs_static(a);
|
needs_static(a);
|
||||||
|
//~^ NOTE argument requires that `x` is borrowed for `'static`
|
||||||
}
|
}
|
||||||
//~^ NOTE `x` dropped here while still borrowed
|
//~^ NOTE `x` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -76,11 +76,11 @@ fn needs_static_mut() {
|
||||||
let a = display_len_mut(&mut x);
|
let a = display_len_mut(&mut x);
|
||||||
//~^ ERROR `x` does not live long enough
|
//~^ ERROR `x` does not live long enough
|
||||||
//~| NOTE this call may capture more lifetimes than intended
|
//~| NOTE this call may capture more lifetimes than intended
|
||||||
//~| NOTE argument requires that `x` is borrowed for `'static`
|
|
||||||
//~| NOTE borrowed value does not live long enough
|
//~| NOTE borrowed value does not live long enough
|
||||||
|
|
||||||
fn needs_static(_: impl Sized + 'static) {}
|
fn needs_static(_: impl Sized + 'static) {}
|
||||||
needs_static(a);
|
needs_static(a);
|
||||||
|
//~^ NOTE argument requires that `x` is borrowed for `'static`
|
||||||
}
|
}
|
||||||
//~^ NOTE `x` dropped here while still borrowed
|
//~^ NOTE `x` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,11 @@ LL | let x = vec![1];
|
||||||
| - binding `x` declared here
|
| - binding `x` declared here
|
||||||
LL |
|
LL |
|
||||||
LL | let a = display_len(&x);
|
LL | let a = display_len(&x);
|
||||||
| ------------^^-
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `x` is borrowed for `'static`
|
|
||||||
...
|
...
|
||||||
|
LL | needs_static(a);
|
||||||
|
| --------------- argument requires that `x` is borrowed for `'static`
|
||||||
|
LL |
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
|
|
||||||
|
@ -118,11 +118,11 @@ LL | let mut x = vec![1];
|
||||||
| ----- binding `x` declared here
|
| ----- binding `x` declared here
|
||||||
LL |
|
LL |
|
||||||
LL | let a = display_len_mut(&mut x);
|
LL | let a = display_len_mut(&mut x);
|
||||||
| ----------------^^^^^^-
|
| ^^^^^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `x` is borrowed for `'static`
|
|
||||||
...
|
...
|
||||||
|
LL | needs_static(a);
|
||||||
|
| --------------- argument requires that `x` is borrowed for `'static`
|
||||||
|
LL |
|
||||||
LL | }
|
LL | }
|
||||||
| - `x` dropped here while still borrowed
|
| - `x` dropped here while still borrowed
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,10 +6,9 @@ LL | fn foo<'a>() {
|
||||||
LL | let y = ();
|
LL | let y = ();
|
||||||
| - binding `y` declared here
|
| - binding `y` declared here
|
||||||
LL | equate(InvariantRef::new(&y), const { InvariantRef::<'a>::NEW });
|
LL | equate(InvariantRef::new(&y), const { InvariantRef::<'a>::NEW });
|
||||||
| ------------------^^-
|
| ^^ ----------------------- using this value as a constant requires that `y` is borrowed for `'a`
|
||||||
| | |
|
| |
|
||||||
| | borrowed value does not live long enough
|
| borrowed value does not live long enough
|
||||||
| argument requires that `y` is borrowed for `'a`
|
|
||||||
LL |
|
LL |
|
||||||
LL | }
|
LL | }
|
||||||
| - `y` dropped here while still borrowed
|
| - `y` dropped here while still borrowed
|
||||||
|
|
|
@ -9,7 +9,7 @@ LL | match InvariantRef::new(&y) {
|
||||||
| ^^ borrowed value does not live long enough
|
| ^^ borrowed value does not live long enough
|
||||||
LL |
|
LL |
|
||||||
LL | const { InvariantRef::<'a>::NEW } => (),
|
LL | const { InvariantRef::<'a>::NEW } => (),
|
||||||
| --------------------------------- type annotation requires that `y` is borrowed for `'a`
|
| ----------------------- using this value as a constant requires that `y` is borrowed for `'a`
|
||||||
LL | }
|
LL | }
|
||||||
LL | }
|
LL | }
|
||||||
| - `y` dropped here while still borrowed
|
| - `y` dropped here while still borrowed
|
||||||
|
|
|
@ -112,13 +112,13 @@ LL | struct Foo; // does not impl Copy
|
||||||
|
|
|
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/kindck-impl-type-params.rs:30:19
|
--> $DIR/kindck-impl-type-params.rs:30:13
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>() {
|
LL | fn foo<'a>() {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let t: S<&'a isize> = S(marker::PhantomData);
|
LL | let t: S<&'a isize> = S(marker::PhantomData);
|
||||||
LL | let a = &t as &dyn Gettable<&'a isize>;
|
LL | let a = &t as &dyn Gettable<&'a isize>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ 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]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| returning this value requires that `'a` must outlive `'static`
|
||||||
|
| requirement occurs due to copying this value
|
||||||
|
|
|
|
||||||
= note: requirement occurs because of the type `Foo<'_>`, which makes the generic argument `'_` invariant
|
= 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`
|
= note: the struct `Foo<'a>` is invariant over the parameter `'a`
|
||||||
|
|
|
@ -7,6 +7,9 @@ LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); }
|
||||||
| | let's call the lifetime of this reference `'1`
|
| | let's call the lifetime of this reference `'1`
|
||||||
| let's call the lifetime of this reference `'2`
|
| let's call the lifetime of this reference `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
||||||
|
@ -21,6 +24,9 @@ LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); }
|
||||||
| | let's call the lifetime of this reference `'1`
|
| | let's call the lifetime of this reference `'1`
|
||||||
| let's call the lifetime of this reference `'2`
|
| let's call the lifetime of this reference `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
||||||
|
@ -35,6 +41,9 @@ LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); }
|
||||||
| | let's call the lifetime of this reference `'1`
|
| | let's call the lifetime of this reference `'1`
|
||||||
| let's call the lifetime of this reference `'2`
|
| let's call the lifetime of this reference `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider reusing a named lifetime parameter
|
help: consider reusing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
||||||
|
|
|
@ -7,9 +7,9 @@ fn inner(mut foo: &[u8]) {
|
||||||
let refcell = RefCell::new(&mut foo);
|
let refcell = RefCell::new(&mut foo);
|
||||||
//~^ ERROR `foo` does not live long enough
|
//~^ ERROR `foo` does not live long enough
|
||||||
let read = &refcell as &RefCell<dyn Read>;
|
let read = &refcell as &RefCell<dyn Read>;
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
|
|
||||||
read_thing(read);
|
read_thing(read);
|
||||||
|
//~^ ERROR borrowed data escapes outside of function
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_thing(refcell: &RefCell<dyn Read>) {}
|
fn read_thing(refcell: &RefCell<dyn Read>) {}
|
||||||
|
|
|
@ -5,22 +5,32 @@ LL | fn inner(mut foo: &[u8]) {
|
||||||
| ------- binding `foo` declared here
|
| ------- binding `foo` declared here
|
||||||
LL | let refcell = RefCell::new(&mut foo);
|
LL | let refcell = RefCell::new(&mut foo);
|
||||||
| ^^^^^^^^ borrowed value does not live long enough
|
| ^^^^^^^^ borrowed value does not live long enough
|
||||||
LL |
|
|
||||||
LL | let read = &refcell as &RefCell<dyn Read>;
|
|
||||||
| ------------------------------ cast requires that `foo` is borrowed for `'static`
|
|
||||||
...
|
...
|
||||||
|
LL | read_thing(read);
|
||||||
|
| ---------------- argument requires that `foo` is borrowed for `'static`
|
||||||
|
LL |
|
||||||
LL | }
|
LL | }
|
||||||
| - `foo` dropped here while still borrowed
|
| - `foo` dropped here while still borrowed
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error[E0521]: borrowed data escapes outside of function
|
||||||
--> $DIR/issue-90600-expected-return-static-indirect.rs:9:16
|
--> $DIR/issue-90600-expected-return-static-indirect.rs:11:5
|
||||||
|
|
|
|
||||||
LL | fn inner(mut foo: &[u8]) {
|
LL | fn inner(mut foo: &[u8]) {
|
||||||
| - let's call the lifetime of this reference `'1`
|
| ------- - let's call the lifetime of this reference `'1`
|
||||||
|
| |
|
||||||
|
| `foo` is a reference that is only valid in the function body
|
||||||
...
|
...
|
||||||
LL | let read = &refcell as &RefCell<dyn Read>;
|
LL | read_thing(read);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| `foo` escapes the function body here
|
||||||
|
| argument requires that `'1` must outlive `'static`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `RefCell<(dyn std::io::Read + 'static)>`, which makes the generic argument `(dyn std::io::Read + 'static)` invariant
|
||||||
|
= note: the struct `RefCell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0597`.
|
Some errors have detailed explanations: E0521, E0597.
|
||||||
|
For more information about an error, try `rustc --explain E0521`.
|
||||||
|
|
|
@ -8,6 +8,9 @@ LL | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
|
||||||
LL | x.push(y);
|
LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_, i32>>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<'a, i32>) {
|
LL | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<'a, i32>) {
|
||||||
|
|
|
@ -10,6 +10,9 @@ LL | x.push(z);
|
||||||
| ^^^^^^^^^ argument requires that `'c` must outlive `'b`
|
| ^^^^^^^^^ argument requires that `'c` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'c: 'b`
|
= help: consider adding the following bound: `'c: 'b`
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_, i32>>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ struct Ref<'a, T: 'a> {
|
||||||
|
|
||||||
fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||||
let a: &mut Vec<Ref<i32>> = x;
|
let a: &mut Vec<Ref<i32>> = x;
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
let b = Ref { data: y.data };
|
let b = Ref { data: y.data };
|
||||||
a.push(b);
|
a.push(b);
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ex2d-push-inference-variable-2.rs:8:5
|
--> $DIR/ex2d-push-inference-variable-2.rs:6:33
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||||
| -- -- lifetime `'c` defined here
|
| -- -- lifetime `'c` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'b` defined here
|
| lifetime `'b` defined here
|
||||||
...
|
LL | let a: &mut Vec<Ref<i32>> = x;
|
||||||
LL | a.push(b);
|
| ^ assignment requires that `'c` must outlive `'b`
|
||||||
| ^^^^^^^^^ argument requires that `'c` must outlive `'b`
|
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'c: 'b`
|
= help: consider adding the following bound: `'c: 'b`
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_, i32>>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ struct Ref<'a, T: 'a> {
|
||||||
|
|
||||||
fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||||
let a: &mut Vec<Ref<i32>> = x;
|
let a: &mut Vec<Ref<i32>> = x;
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
let b = Ref { data: y.data };
|
let b = Ref { data: y.data };
|
||||||
Vec::push(a, b);
|
Vec::push(a, b);
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ex2e-push-inference-variable-3.rs:8:5
|
--> $DIR/ex2e-push-inference-variable-3.rs:6:33
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
|
||||||
| -- -- lifetime `'c` defined here
|
| -- -- lifetime `'c` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'b` defined here
|
| lifetime `'b` defined here
|
||||||
...
|
LL | let a: &mut Vec<Ref<i32>> = x;
|
||||||
LL | Vec::push(a, b);
|
| ^ assignment requires that `'c` must outlive `'b`
|
||||||
| ^^^^^^^^^^^^^^^ argument requires that `'c` must outlive `'b`
|
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'c: 'b`
|
= help: consider adding the following bound: `'c: 'b`
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_, i32>>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||||
LL | z.push((x,y));
|
LL | z.push((x,y));
|
||||||
| ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<(&u8, &u8)>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) {
|
LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) {
|
||||||
|
@ -23,6 +26,9 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
|
||||||
LL | z.push((x,y));
|
LL | z.push((x,y));
|
||||||
| ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4`
|
| ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<(&u8, &u8)>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) {
|
LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) {
|
||||||
|
|
|
@ -10,6 +10,9 @@ LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_>>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@ LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_>>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,9 @@ LL | fn foo(mut x: Vec<Ref>, y: Ref) {
|
||||||
LL | x.push(y);
|
LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<Ref<'_>>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(mut x: Vec<Ref<'a>>, y: Ref<'a>) {
|
LL | fn foo<'a>(mut x: Vec<Ref<'a>>, y: Ref<'a>) {
|
||||||
|
|
|
@ -9,6 +9,9 @@ LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= note: mutable references are invariant over their type parameter
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,9 @@ LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
|
||||||
LL | y.push(z);
|
LL | y.push(z);
|
||||||
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
|
LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
|
||||||
|
|
|
@ -8,6 +8,9 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
|
||||||
LL | x.push(y);
|
LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter and update trait if needed
|
help: consider introducing a named lifetime parameter and update trait if needed
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
|
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
|
||||||
|
|
|
@ -19,6 +19,9 @@ LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
|
||||||
LL | y.push(z);
|
LL | y.push(z);
|
||||||
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&'a u8>, z: &'a u8) {
|
LL | fn foo<'a>(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&'a u8>, z: &'a u8) {
|
||||||
|
|
|
@ -8,6 +8,9 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
|
||||||
LL | x.push(y);
|
LL | x.push(y);
|
||||||
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
|
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
|
||||||
|
|
|
@ -23,6 +23,10 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| {
|
||||||
...
|
...
|
||||||
LL | demand_y(x, y, p)
|
LL | demand_y(x, y, p)
|
||||||
| ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?34 u32>`, which makes the generic argument `&'?34 u32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
note: no external requirements
|
note: no external requirements
|
||||||
--> $DIR/propagate-approximated-fail-no-postdom.rs:38:1
|
--> $DIR/propagate-approximated-fail-no-postdom.rs:38:1
|
||||||
|
|
|
@ -41,9 +41,10 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
|
||||||
#[rustc_regions]
|
#[rustc_regions]
|
||||||
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
|
|
||||||
// Only works if 'x: 'y:
|
// Only works if 'x: 'y:
|
||||||
demand_y(x, y, x.get())
|
demand_y(x, y, x.get())
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,21 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
= note: defining type: supply
|
= note: defining type: supply
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/propagate-approximated-ref.rs:45:9
|
--> $DIR/propagate-approximated-ref.rs:43:5
|
||||||
|
|
|
|
||||||
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||||
LL | demand_y(x, y, x.get())
|
... |
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
LL | | });
|
||||||
|
| |______^ argument requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?11 u32>`, which makes the generic argument `&'?11 u32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@ LL | foo(cell, |cell_a, cell_x| {
|
||||||
| `cell_a` declared here, outside of the closure body
|
| `cell_a` declared here, outside of the closure body
|
||||||
LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
|
LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?8 u32>`, which makes the generic argument `&'?8 u32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
note: no external requirements
|
note: no external requirements
|
||||||
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1
|
--> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1
|
||||||
|
@ -56,11 +60,11 @@ error[E0597]: `a` does not live long enough
|
||||||
LL | let a = 0;
|
LL | let a = 0;
|
||||||
| - binding `a` declared here
|
| - binding `a` declared here
|
||||||
LL | let cell = Cell::new(&a);
|
LL | let cell = Cell::new(&a);
|
||||||
| ----------^^-
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `a` is borrowed for `'static`
|
|
||||||
...
|
...
|
||||||
|
LL | cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error
|
||||||
|
| ------------------------ argument requires that `a` is borrowed for `'static`
|
||||||
|
LL | })
|
||||||
LL | }
|
LL | }
|
||||||
| - `a` dropped here while still borrowed
|
| - `a` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
|
||||||
#[rustc_regions]
|
#[rustc_regions]
|
||||||
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||||
//~^ ERROR borrowed data escapes outside of function
|
|
||||||
|
|
||||||
// Only works if 'x: 'y:
|
// Only works if 'x: 'y:
|
||||||
demand_y(x, y, x.get())
|
demand_y(x, y, x.get())
|
||||||
|
//~^ ERROR borrowed data escapes outside of function
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,23 +23,18 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
= note: defining type: supply
|
= note: defining type: supply
|
||||||
|
|
||||||
error[E0521]: borrowed data escapes outside of function
|
error[E0521]: borrowed data escapes outside of function
|
||||||
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:32:5
|
--> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:34:9
|
||||||
|
|
|
|
||||||
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
| -- ------ `cell_a` is a reference that is only valid in the function body
|
| -- ------ `cell_a` is a reference that is only valid in the function body
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
...
|
||||||
... |
|
LL | demand_y(x, y, x.get())
|
||||||
LL | | });
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| | ^
|
| |
|
||||||
| | |
|
| `cell_a` escapes the function body here
|
||||||
| |______`cell_a` escapes the function body here
|
|
||||||
| argument requires that `'a` must outlive `'static`
|
| argument requires that `'a` must outlive `'static`
|
||||||
|
|
|
||||||
= note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant
|
|
||||||
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
|
||||||
= 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
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,9 @@ fn demand_y<'x, 'y>(_cell_x: &Cell<&'x u32>, _cell_y: &Cell<&'y u32>, _y: &'y u3
|
||||||
#[rustc_regions]
|
#[rustc_regions]
|
||||||
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
||||||
//~^ ERROR borrowed data escapes outside of function
|
|
||||||
|
|
||||||
// Only works if 'x: 'y:
|
// Only works if 'x: 'y:
|
||||||
demand_y(x, y, x.get())
|
demand_y(x, y, x.get())
|
||||||
|
//~^ ERROR borrowed data escapes outside of function
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,23 +23,18 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
= note: defining type: supply
|
= note: defining type: supply
|
||||||
|
|
||||||
error[E0521]: borrowed data escapes outside of function
|
error[E0521]: borrowed data escapes outside of function
|
||||||
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:35:5
|
--> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:37:9
|
||||||
|
|
|
|
||||||
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
| -- ------ `cell_a` is a reference that is only valid in the function body
|
| -- ------ `cell_a` is a reference that is only valid in the function body
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
|
...
|
||||||
... |
|
LL | demand_y(x, y, x.get())
|
||||||
LL | | });
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
| | ^
|
| |
|
||||||
| | |
|
| `cell_a` escapes the function body here
|
||||||
| |______`cell_a` escapes the function body here
|
|
||||||
| argument requires that `'a` must outlive `'static`
|
| argument requires that `'a` must outlive `'static`
|
||||||
|
|
|
||||||
= note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant
|
|
||||||
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
|
||||||
= 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
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,10 @@ fn demand_y<'x, 'y>(_outlives1: Cell<&&'x u32>, _outlives2: Cell<&'y &u32>, _y:
|
||||||
#[rustc_regions]
|
#[rustc_regions]
|
||||||
fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
|
|
||||||
// Only works if 'x: 'y:
|
// Only works if 'x: 'y:
|
||||||
demand_y(outlives1, outlives2, x.get())
|
demand_y(outlives1, outlives2, x.get())
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,21 @@ LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
= note: defining type: test
|
= note: defining type: test
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/propagate-approximated-val.rs:38:9
|
--> $DIR/propagate-approximated-val.rs:36:5
|
||||||
|
|
|
|
||||||
LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
LL | / establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
|
||||||
LL | demand_y(outlives1, outlives2, x.get())
|
... |
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
LL | | });
|
||||||
|
| |______^ argument requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?7 u32>`, which makes the generic argument `&'?7 u32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,10 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
|
||||||
LL | // Only works if 'x: 'y:
|
LL | // Only works if 'x: 'y:
|
||||||
LL | demand_y(x, y, x.get())
|
LL | demand_y(x, y, x.get())
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?37 u32>`, which makes the generic argument `&'?37 u32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
note: no external requirements
|
note: no external requirements
|
||||||
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1
|
--> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1
|
||||||
|
|
|
@ -22,6 +22,10 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
|
||||||
LL | // Only works if 'x: 'y:
|
LL | // Only works if 'x: 'y:
|
||||||
LL | demand_y(x, y, x.get())
|
LL | demand_y(x, y, x.get())
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?43 u32>`, which makes the generic argument `&'?43 u32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
note: no external requirements
|
note: no external requirements
|
||||||
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1
|
--> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1
|
||||||
|
|
|
@ -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); //~ ERROR: 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`.
|
||||||
|
|
|
@ -17,10 +17,9 @@ LL | fn to_refs<T>(mut list: [&mut List<T>; 2]) -> Vec<&mut T> {
|
||||||
| - let's call the lifetime of this reference `'1`
|
| - let's call the lifetime of this reference `'1`
|
||||||
...
|
...
|
||||||
LL | if let Some(n) = list[0].next.as_mut() {
|
LL | if let Some(n) = list[0].next.as_mut() {
|
||||||
| ^^^^^^^^^^^^---------
|
| ^^^^^^^^^^^^ `list[_].next` was mutably borrowed here in the previous iteration of the loop
|
||||||
| |
|
LL | list[0] = n;
|
||||||
| `list[_].next` was mutably borrowed here in the previous iteration of the loop
|
| ----------- assignment requires that `list[_].next` is borrowed for `'1`
|
||||||
| argument requires that `list[_].next` is borrowed for `'1`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,9 @@ LL | fn to_refs<'a, T>(mut list: (&'a mut List<T>, &'a mut List<T>)) -> Vec<&'a
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | if let Some(n) = (list.0).next.as_mut() {
|
LL | if let Some(n) = (list.0).next.as_mut() {
|
||||||
| ^^^^^^^^^^^^^---------
|
| ^^^^^^^^^^^^^ `list.0.next` was mutably borrowed here in the previous iteration of the loop
|
||||||
| |
|
LL | list.1 = n;
|
||||||
| `list.0.next` was mutably borrowed here in the previous iteration of the loop
|
| ---------- assignment requires that `list.0.next` is borrowed for `'a`
|
||||||
| argument requires that `list.0.next` is borrowed for `'a`
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ struct Consumer<'tcx>(&'tcx ());
|
||||||
|
|
||||||
impl<'tcx> Consumer<'tcx> {
|
impl<'tcx> Consumer<'tcx> {
|
||||||
fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
||||||
let other = self.use_fcx(fcx); //~ ERROR lifetime may not live long enough
|
let other = self.use_fcx(fcx);
|
||||||
fcx.use_it(other);
|
fcx.use_it(other); //~ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_fcx<'a>(&self, _: &FnCtxt<'a, 'tcx>) -> &'a () {
|
fn use_fcx<'a>(&self, _: &FnCtxt<'a, 'tcx>) -> &'a () {
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-67007-escaping-data.rs:15:21
|
--> $DIR/issue-67007-escaping-data.rs:16:9
|
||||||
|
|
|
|
||||||
LL | impl<'tcx> Consumer<'tcx> {
|
LL | impl<'tcx> Consumer<'tcx> {
|
||||||
| ---- lifetime `'tcx` defined here
|
| ---- lifetime `'tcx` defined here
|
||||||
LL | fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
LL | fn bad_method<'a>(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let other = self.use_fcx(fcx);
|
LL | let other = self.use_fcx(fcx);
|
||||||
|
LL | fcx.use_it(other);
|
||||||
| ^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'tcx`
|
| ^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'tcx`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'tcx`
|
= help: consider adding the following bound: `'a: 'tcx`
|
||||||
|
= note: requirement occurs because of the type `FnCtxt<'_, '_>`, which makes the generic argument `'_` invariant
|
||||||
|
= note: the struct `FnCtxt<'a, 'tcx>` is invariant over the parameter `'tcx`
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ where
|
||||||
|
|
||||||
fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) {
|
fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) {
|
||||||
let f = check;
|
let f = check;
|
||||||
//~^ ERROR lifetime may not live long enough
|
|
||||||
f(x, y);
|
f(x, y);
|
||||||
|
//~^ ERROR lifetime may not live long enough
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-95272.rs:10:13
|
--> $DIR/issue-95272.rs:11:5
|
||||||
|
|
|
|
||||||
LL | fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) {
|
LL | fn test<'a, 'b>(x: Cell<&'a ()>, y: Cell<&'b ()>) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let f = check;
|
LL | let f = check;
|
||||||
| ^^^^^ assignment requires that `'a` must outlive `'b`
|
LL | f(x, y);
|
||||||
|
| ^^^^^^^ argument requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `check`
|
= note: requirement occurs because of the type `Cell<&()>`, which makes the generic argument `&()` invariant
|
||||||
= note: the function `check` is invariant over the parameter `'a`
|
= note: the struct `Cell<T>` 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
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -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`
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,10 @@ LL | fn get_bar(&self) -> Bar2 {
|
||||||
| - let's call the lifetime of this reference `'1`
|
| - let's call the lifetime of this reference `'1`
|
||||||
LL | Bar2::new(&self)
|
LL | Bar2::new(&self)
|
||||||
| ^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Foo2<'_>`, which makes the generic argument `'_` invariant
|
||||||
|
= note: the struct `Foo2<'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 9 previous errors
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ LL | fn assignment_to_field_projection<'a, T>(
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | if let Some(n) = (list.0).next.as_mut() {
|
LL | if let Some(n) = (list.0).next.as_mut() {
|
||||||
| ^^^^^^^^^^^^^---------
|
| ^^^^^^^^^^^^^ `list.0.next` was mutably borrowed here in the previous iteration of the loop
|
||||||
| |
|
LL |
|
||||||
| `list.0.next` was mutably borrowed here in the previous iteration of the loop
|
LL | list.1 = n;
|
||||||
| argument requires that `list.0.next` is borrowed for `'a`
|
| ---------- assignment requires that `list.0.next` is borrowed for `'a`
|
||||||
|
|
||||||
error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time
|
error[E0499]: cannot borrow `list.0.0.0.0.0.value` as mutable more than once at a time
|
||||||
--> $DIR/assignment-to-differing-field.rs:37:21
|
--> $DIR/assignment-to-differing-field.rs:37:21
|
||||||
|
@ -41,10 +41,10 @@ LL | fn assignment_through_projection_chain<'a, T>(
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
|
LL | if let Some(n) = ((((list.0).0).0).0).0.next.as_mut() {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^---------
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `list.0.0.0.0.0.next` was mutably borrowed here in the previous iteration of the loop
|
||||||
| |
|
LL |
|
||||||
| `list.0.0.0.0.0.next` was mutably borrowed here in the previous iteration of the loop
|
LL | *((((list.0).0).0).0).1 = n;
|
||||||
| argument requires that `list.0.0.0.0.0.next` is borrowed for `'a`
|
| --------------------------- assignment requires that `list.0.0.0.0.0.next` is borrowed for `'a`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@ LL | let b = 44;
|
||||||
| - binding `b` declared here
|
| - binding `b` declared here
|
||||||
...
|
...
|
||||||
LL | let x: DoubleCell<_> = make_cell(&b);
|
LL | let x: DoubleCell<_> = make_cell(&b);
|
||||||
| ------------- ^^ borrowed value does not live long enough
|
| ----------^^-
|
||||||
| |
|
| | |
|
||||||
| type annotation requires that `b` is borrowed for `'static`
|
| | borrowed value does not live long enough
|
||||||
|
| assignment requires that `b` is borrowed for `'static`
|
||||||
...
|
...
|
||||||
LL | }
|
LL | }
|
||||||
| - `b` dropped here while still borrowed
|
| - `b` dropped here while still borrowed
|
||||||
|
|
|
@ -24,6 +24,22 @@ LL | | T: Anything<'b>,
|
||||||
|
|
|
|
||||||
= note: defining type: no_relationships_late::<'?1, T>
|
= note: defining type: no_relationships_late::<'?1, T>
|
||||||
|
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/projection-one-region-closure.rs:45:5
|
||||||
|
|
|
||||||
|
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||||
|
| -- -- lifetime `'b` defined here
|
||||||
|
| |
|
||||||
|
| lifetime `'a` defined here
|
||||||
|
...
|
||||||
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
||||||
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?6 ()>`, which makes the generic argument `&'?6 ()` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error[E0309]: the parameter type `T` may not live long enough
|
error[E0309]: the parameter type `T` may not live long enough
|
||||||
--> $DIR/projection-one-region-closure.rs:45:39
|
--> $DIR/projection-one-region-closure.rs:45:39
|
||||||
|
|
|
|
||||||
|
@ -38,19 +54,6 @@ help: consider adding an explicit lifetime bound
|
||||||
LL | T: Anything<'b> + 'a,
|
LL | T: Anything<'b> + 'a,
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
|
||||||
--> $DIR/projection-one-region-closure.rs:45:39
|
|
||||||
|
|
|
||||||
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
|
||||||
| -- -- lifetime `'b` defined here
|
|
||||||
| |
|
|
||||||
| lifetime `'a` defined here
|
|
||||||
...
|
|
||||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
|
||||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
|
||||||
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
|
||||||
|
|
||||||
note: external requirements
|
note: external requirements
|
||||||
--> $DIR/projection-one-region-closure.rs:56:29
|
--> $DIR/projection-one-region-closure.rs:56:29
|
||||||
|
|
|
|
||||||
|
@ -77,6 +80,22 @@ LL | | 'a: 'a,
|
||||||
|
|
|
|
||||||
= note: defining type: no_relationships_early::<'?1, '?2, T>
|
= note: defining type: no_relationships_early::<'?1, '?2, T>
|
||||||
|
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/projection-one-region-closure.rs:56:5
|
||||||
|
|
|
||||||
|
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||||
|
| -- -- lifetime `'b` defined here
|
||||||
|
| |
|
||||||
|
| lifetime `'a` defined here
|
||||||
|
...
|
||||||
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
||||||
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?7 ()>`, which makes the generic argument `&'?7 ()` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error[E0309]: the parameter type `T` may not live long enough
|
error[E0309]: the parameter type `T` may not live long enough
|
||||||
--> $DIR/projection-one-region-closure.rs:56:39
|
--> $DIR/projection-one-region-closure.rs:56:39
|
||||||
|
|
|
|
||||||
|
@ -91,19 +110,6 @@ help: consider adding an explicit lifetime bound
|
||||||
LL | T: Anything<'b> + 'a,
|
LL | T: Anything<'b> + 'a,
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
|
||||||
--> $DIR/projection-one-region-closure.rs:56:39
|
|
||||||
|
|
|
||||||
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
|
||||||
| -- -- lifetime `'b` defined here
|
|
||||||
| |
|
|
||||||
| lifetime `'a` defined here
|
|
||||||
...
|
|
||||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
|
||||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
|
||||||
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
|
||||||
|
|
||||||
note: external requirements
|
note: external requirements
|
||||||
--> $DIR/projection-one-region-closure.rs:70:29
|
--> $DIR/projection-one-region-closure.rs:70:29
|
||||||
|
|
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ LL | | T: Anything<'b>,
|
||||||
= note: defining type: no_relationships_late::<'?1, T>
|
= note: defining type: no_relationships_late::<'?1, T>
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/projection-one-region-trait-bound-closure.rs:37:39
|
--> $DIR/projection-one-region-trait-bound-closure.rs:37:5
|
||||||
|
|
|
|
||||||
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
|
@ -32,9 +32,12 @@ LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?6 ()>`, which makes the generic argument `&'?6 ()` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
note: external requirements
|
note: external requirements
|
||||||
--> $DIR/projection-one-region-trait-bound-closure.rs:47:29
|
--> $DIR/projection-one-region-trait-bound-closure.rs:47:29
|
||||||
|
@ -62,7 +65,7 @@ LL | | 'a: 'a,
|
||||||
= note: defining type: no_relationships_early::<'?1, '?2, T>
|
= note: defining type: no_relationships_early::<'?1, '?2, T>
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/projection-one-region-trait-bound-closure.rs:47:39
|
--> $DIR/projection-one-region-trait-bound-closure.rs:47:5
|
||||||
|
|
|
|
||||||
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
|
@ -70,9 +73,12 @@ LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of the type `Cell<&'?7 ()>`, which makes the generic argument `&'?7 ()` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
note: external requirements
|
note: external requirements
|
||||||
--> $DIR/projection-one-region-trait-bound-closure.rs:60:29
|
--> $DIR/projection-one-region-trait-bound-closure.rs:60:29
|
||||||
|
|
|
@ -182,7 +182,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of the type `Cell<&'?8 ()>`, which makes the generic argument `&'?8 ()` invariant
|
= note: requirement occurs because of the type `Cell<&'?6 ()>`, which makes the generic argument `&'?6 ()` invariant
|
||||||
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
= note: the struct `Cell<T>` 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
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ 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`
|
| ^^^^^^ argument requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= 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`
|
||||||
|
@ -14,14 +14,14 @@ LL | x == y;
|
||||||
= 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
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-comparisons.rs:4:10
|
--> $DIR/type-check-pointer-comparisons.rs:4:5
|
||||||
|
|
|
|
||||||
LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
|
LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x == y;
|
LL | x == y;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= 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`
|
||||||
|
@ -38,7 +38,7 @@ 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`
|
| ^^^^^^ argument requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= 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`
|
||||||
|
@ -46,14 +46,14 @@ LL | x == y;
|
||||||
= 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
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-comparisons.rs:10:10
|
--> $DIR/type-check-pointer-comparisons.rs:10:5
|
||||||
|
|
|
|
||||||
LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
|
LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x == y;
|
LL | x == y;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= 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 `&i32`
|
= note: requirement occurs because of a mutable pointer to `&i32`
|
||||||
|
@ -72,7 +72,7 @@ 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`
|
| ^^^^^^ argument requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= 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`
|
||||||
|
@ -80,14 +80,14 @@ LL | f == g;
|
||||||
= 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
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-comparisons.rs:16:10
|
--> $DIR/type-check-pointer-comparisons.rs:16:5
|
||||||
|
|
|
|
||||||
LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
|
LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32)) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | f == g;
|
LL | f == g;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^^^^^^ argument requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= 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`
|
||||||
|
|
|
@ -3,13 +3,12 @@ error[E0597]: `c` does not live long enough
|
||||||
|
|
|
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | combine(
|
LL | / combine(
|
||||||
LL | SomeEnum::SomeVariant(Cell::new(&c)),
|
LL | | SomeEnum::SomeVariant(Cell::new(&c)),
|
||||||
| ----------^^-
|
| | ^^ borrowed value does not live long enough
|
||||||
| | |
|
LL | | SomeEnum::SomeOtherVariant::<Cell<&'static u32>>,
|
||||||
| | borrowed value does not live long enough
|
LL | | );
|
||||||
| argument requires that `c` is borrowed for `'static`
|
| |_____- argument requires that `c` is borrowed for `'static`
|
||||||
...
|
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -20,13 +19,12 @@ LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | combine(
|
LL | / combine(
|
||||||
LL | SomeEnum::SomeVariant(Cell::new(&c)),
|
LL | | SomeEnum::SomeVariant(Cell::new(&c)),
|
||||||
| ----------^^-
|
| | ^^ borrowed value does not live long enough
|
||||||
| | |
|
LL | | SomeEnum::SomeOtherVariant::<Cell<&'a u32>>,
|
||||||
| | borrowed value does not live long enough
|
LL | | );
|
||||||
| argument requires that `c` is borrowed for `'a`
|
| |_____- argument requires that `c` is borrowed for `'a`
|
||||||
...
|
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -38,13 +36,12 @@ LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
|
||||||
LL | let _closure = || {
|
LL | let _closure = || {
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | combine(
|
LL | / combine(
|
||||||
LL | SomeEnum::SomeVariant(Cell::new(&c)),
|
LL | | SomeEnum::SomeVariant(Cell::new(&c)),
|
||||||
| ----------^^-
|
| | ^^ borrowed value does not live long enough
|
||||||
| | |
|
LL | | SomeEnum::SomeOtherVariant::<Cell<&'a u32>>,
|
||||||
| | borrowed value does not live long enough
|
LL | | );
|
||||||
| argument requires that `c` is borrowed for `'a`
|
| |_________- argument requires that `c` is borrowed for `'a`
|
||||||
...
|
|
||||||
LL | };
|
LL | };
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,9 @@ error[E0597]: `c` does not live long enough
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | let f = SomeStruct::<&'static u32>;
|
LL | let f = SomeStruct::<&'static u32>;
|
||||||
|
| -------------------------- assignment requires that `c` is borrowed for `'static`
|
||||||
LL | f(&c);
|
LL | f(&c);
|
||||||
| --^^-
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `c` is borrowed for `'static`
|
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -20,11 +18,9 @@ LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | let f = SomeStruct::<&'a u32>;
|
LL | let f = SomeStruct::<&'a u32>;
|
||||||
|
| --------------------- assignment requires that `c` is borrowed for `'a`
|
||||||
LL | f(&c);
|
LL | f(&c);
|
||||||
| --^^-
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `c` is borrowed for `'a`
|
|
||||||
LL | }
|
LL | }
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
@ -37,11 +33,9 @@ LL | let _closure = || {
|
||||||
LL | let c = 66;
|
LL | let c = 66;
|
||||||
| - binding `c` declared here
|
| - binding `c` declared here
|
||||||
LL | let f = SomeStruct::<&'a u32>;
|
LL | let f = SomeStruct::<&'a u32>;
|
||||||
|
| --------------------- assignment requires that `c` is borrowed for `'a`
|
||||||
LL | f(&c);
|
LL | f(&c);
|
||||||
| --^^-
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `c` is borrowed for `'a`
|
|
||||||
LL | };
|
LL | };
|
||||||
| - `c` dropped here while still borrowed
|
| - `c` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,10 @@ error[E0597]: `a` does not live long enough
|
||||||
LL | let a = 22;
|
LL | let a = 22;
|
||||||
| - binding `a` declared here
|
| - binding `a` declared here
|
||||||
...
|
...
|
||||||
|
LL | let x = <&'static u32 as Bazoom<_>>::method;
|
||||||
|
| ----------------------------------- assignment requires that `a` is borrowed for `'static`
|
||||||
LL | x(&a, b, c);
|
LL | x(&a, b, c);
|
||||||
| --^^-------
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `a` is borrowed for `'static`
|
|
||||||
LL | }
|
LL | }
|
||||||
| - `a` dropped here while still borrowed
|
| - `a` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,10 @@ error[E0597]: `a` does not live long enough
|
||||||
LL | let a = 22;
|
LL | let a = 22;
|
||||||
| - binding `a` declared here
|
| - binding `a` declared here
|
||||||
...
|
...
|
||||||
|
LL | let x = <&'static u32 as Bazoom<_>>::method;
|
||||||
|
| ----------------------------------- assignment requires that `a` is borrowed for `'static`
|
||||||
LL | x(&a, b, c);
|
LL | x(&a, b, c);
|
||||||
| --^^-------
|
| ^^ borrowed value does not live long enough
|
||||||
| | |
|
|
||||||
| | borrowed value does not live long enough
|
|
||||||
| argument requires that `a` is borrowed for `'static`
|
|
||||||
LL | }
|
LL | }
|
||||||
| - `a` dropped here while still borrowed
|
| - `a` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/where_clauses_in_structs.rs:11:11
|
--> $DIR/where_clauses_in_structs.rs:11:14
|
||||||
|
|
|
|
||||||
LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) {
|
LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
//! diagnostic test for #132749: ensure we pick a decent span and reason to blame for region errors
|
||||||
|
//! when failing to prove a region outlives 'static
|
||||||
|
|
||||||
|
struct Bytes(&'static [u8]);
|
||||||
|
|
||||||
|
fn deserialize_simple_string(buf: &[u8]) -> (Bytes, &[u8]) {
|
||||||
|
//~^ NOTE let's call the lifetime of this reference `'1`
|
||||||
|
let (s, rest) = buf.split_at(2);
|
||||||
|
(Bytes(s), rest) //~ ERROR lifetime may not live long enough
|
||||||
|
//~| NOTE this usage requires that `'1` must outlive `'static`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/better-blame-constraint-for-outlives-static.rs:9:12
|
||||||
|
|
|
||||||
|
LL | fn deserialize_simple_string(buf: &[u8]) -> (Bytes, &[u8]) {
|
||||||
|
| - let's call the lifetime of this reference `'1`
|
||||||
|
...
|
||||||
|
LL | (Bytes(s), rest)
|
||||||
|
| ^ this usage requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -25,6 +25,10 @@ LL | self.enter_scope(|ctx| {
|
||||||
| has type `&mut FooImpl<'2, '_, T>`
|
| has type `&mut FooImpl<'2, '_, T>`
|
||||||
LL | BarImpl(ctx);
|
LL | BarImpl(ctx);
|
||||||
| ^^^ this usage requires that `'1` must outlive `'2`
|
| ^^^ this usage requires that `'1` must outlive `'2`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `FooImpl<'_, '_, T>`
|
||||||
|
= note: mutable references 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/lifetime-not-long-enough-suggestion-regression-test-124563.rs:22:9
|
--> $DIR/lifetime-not-long-enough-suggestion-regression-test-124563.rs:22:9
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// over time, but this test used to exhibit some pretty bogus messages
|
// over time, but this test used to exhibit some pretty bogus messages
|
||||||
// that were not remotely helpful.
|
// that were not remotely helpful.
|
||||||
|
|
||||||
//@ error-pattern:argument requires that `'a` must outlive `'static`
|
//@ error-pattern:requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
struct Invariant<'a>(Option<&'a mut &'a mut ()>);
|
struct Invariant<'a>(Option<&'a mut &'a mut ()>);
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ fn mk_static() -> Invariant<'static> { Invariant(None) }
|
||||||
|
|
||||||
fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
|
fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
|
||||||
let bad = if x.is_some() {
|
let bad = if x.is_some() {
|
||||||
x.unwrap() //~ ERROR borrowed data escapes outside of function [E0521]
|
x.unwrap()
|
||||||
} else {
|
} else {
|
||||||
mk_static()
|
mk_static() //~ ERROR lifetime may not live long enough
|
||||||
};
|
};
|
||||||
f(bad);
|
f(bad);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
error[E0521]: borrowed data escapes outside of function
|
error: lifetime may not live long enough
|
||||||
--> $DIR/region-invariant-static-error-reporting.rs:14:9
|
--> $DIR/region-invariant-static-error-reporting.rs:16:9
|
||||||
|
|
|
|
||||||
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
|
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
|
||||||
| -- - `x` is a reference that is only valid in the function body
|
| -- lifetime `'a` defined here
|
||||||
| |
|
...
|
||||||
| lifetime `'a` defined here
|
LL | mk_static()
|
||||||
LL | let bad = if x.is_some() {
|
| ^^^^^^^^^^^ assignment requires that `'a` must outlive `'static`
|
||||||
LL | x.unwrap()
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| `x` escapes the function body here
|
|
||||||
| argument requires that `'a` must outlive `'static`
|
|
||||||
|
|
|
|
||||||
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
|
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
|
||||||
= note: the struct `Invariant<'a>` is invariant over the parameter `'a`
|
= note: the struct `Invariant<'a>` is invariant over the parameter `'a`
|
||||||
|
@ -18,4 +13,3 @@ LL | x.unwrap()
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0521`.
|
|
||||||
|
|
|
@ -4,11 +4,9 @@ error[E0597]: `person` does not live long enough
|
||||||
LL | let person = "Fred".to_string();
|
LL | let person = "Fred".to_string();
|
||||||
| ------ binding `person` declared here
|
| ------ binding `person` declared here
|
||||||
LL | let person: &str = &person;
|
LL | let person: &str = &person;
|
||||||
| ^^^^^^^
|
| ^^^^^^^ borrowed value does not live long enough
|
||||||
| |
|
|
||||||
| borrowed value does not live long enough
|
|
||||||
| assignment requires that `person` is borrowed for `'static`
|
|
||||||
LL | let s: Box<dyn Trait<&'static str>> = Box::new(Struct { person: person });
|
LL | let s: Box<dyn Trait<&'static str>> = Box::new(Struct { person: person });
|
||||||
|
| ------ this usage requires that `person` is borrowed for `'static`
|
||||||
LL | }
|
LL | }
|
||||||
| - `person` dropped here while still borrowed
|
| - `person` dropped here while still borrowed
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-checking-test-3.rs:11:18
|
--> $DIR/type-checking-test-3.rs:11:13
|
||||||
|
|
|
|
||||||
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let _ = x as &dyn Bar<'a>; // Error
|
LL | let _ = x as &dyn Bar<'a>; // Error
|
||||||
| ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-checking-test-3.rs:16:18
|
--> $DIR/type-checking-test-3.rs:16:18
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-checking-test-4.rs:19:18
|
--> $DIR/type-checking-test-4.rs:19:13
|
||||||
|
|
|
|
||||||
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
|
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-checking-test-4.rs:24:18
|
--> $DIR/type-checking-test-4.rs:24:18
|
||||||
|
|
|
@ -7,6 +7,10 @@ LL | doit(0, &|x, y| {
|
||||||
| has type `&Cell<&'2 i32>`
|
| has type `&Cell<&'2 i32>`
|
||||||
LL | x.set(y);
|
LL | x.set(y);
|
||||||
| ^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Cell<&i32>`, which makes the generic argument `&i32` invariant
|
||||||
|
= note: the struct `Cell<T>` is invariant over the parameter `T`
|
||||||
|
= 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
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); }
|
||||||
| | let's call the lifetime of this reference `'1`
|
| | let's call the lifetime of this reference `'1`
|
||||||
| let's call the lifetime of this reference `'2`
|
| let's call the lifetime of this reference `'2`
|
||||||
|
|
|
|
||||||
|
= note: requirement occurs because of a mutable reference to `Vec<&u8>`
|
||||||
|
= 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: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/variance-associated-types2.rs:13:12
|
--> $DIR/variance-associated-types2.rs:13:42
|
||||||
|
|
|
|
||||||
LL | fn take<'a>(_: &'a u32) {
|
LL | fn take<'a>(_: &'a u32) {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | let _: Box<dyn Foo<Bar = &'a u32>> = make();
|
LL | let _: Box<dyn Foo<Bar = &'a u32>> = make();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^ coercion requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue