implement outlive suggestions
This commit is contained in:
parent
b7176b44a2
commit
3a1847b07d
@ -6,7 +6,7 @@ use crate::Applicability;
|
||||
use crate::Level;
|
||||
use crate::snippet::Style;
|
||||
use std::fmt;
|
||||
use syntax_pos::{MultiSpan, Span};
|
||||
use syntax_pos::{MultiSpan, Span, DUMMY_SP};
|
||||
|
||||
#[must_use]
|
||||
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
|
||||
@ -17,6 +17,11 @@ pub struct Diagnostic {
|
||||
pub span: MultiSpan,
|
||||
pub children: Vec<SubDiagnostic>,
|
||||
pub suggestions: Vec<CodeSuggestion>,
|
||||
|
||||
/// This is not used for highlighting or rendering any error message. Rather, it can be used
|
||||
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
|
||||
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
|
||||
pub sort_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
@ -87,6 +92,7 @@ impl Diagnostic {
|
||||
span: MultiSpan::new(),
|
||||
children: vec![],
|
||||
suggestions: vec![],
|
||||
sort_span: DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +124,11 @@ impl Diagnostic {
|
||||
self.level == Level::Cancelled
|
||||
}
|
||||
|
||||
/// Set the sorting span.
|
||||
pub fn set_sort_span(&mut self, sp: Span) {
|
||||
self.sort_span = sp;
|
||||
}
|
||||
|
||||
/// Adds a span/label to be included in the resulting snippet.
|
||||
/// This label will be shown together with the original span/label used when creating the
|
||||
/// diagnostic, *not* a span added by one of the `span_*` methods.
|
||||
@ -457,6 +468,9 @@ impl Diagnostic {
|
||||
|
||||
pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
|
||||
self.span = sp.into();
|
||||
if let Some(span) = self.span.primary_span() {
|
||||
self.sort_span = span;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -367,7 +367,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||
}
|
||||
|
||||
if !mbcx.errors_buffer.is_empty() {
|
||||
mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span());
|
||||
mbcx.errors_buffer.sort_by_key(|diag| diag.sort_span);
|
||||
|
||||
for diag in mbcx.errors_buffer.drain(..) {
|
||||
mbcx.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag);
|
||||
|
@ -18,6 +18,10 @@ use syntax::errors::Applicability;
|
||||
use syntax::symbol::kw;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use self::outlives_suggestion::OutlivesSuggestionBuilder;
|
||||
|
||||
pub mod outlives_suggestion;
|
||||
|
||||
mod region_name;
|
||||
mod var_name;
|
||||
|
||||
@ -56,7 +60,6 @@ enum Trace {
|
||||
/// Various pieces of state used when reporting borrow checker errors.
|
||||
pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
|
||||
/// The region inference context used for borrow chekcing this MIR body.
|
||||
#[allow(dead_code)] // FIXME(mark-i-m): used by outlives suggestions
|
||||
region_infcx: &'b RegionInferenceContext<'tcx>,
|
||||
|
||||
/// The inference context used for type checking.
|
||||
@ -370,6 +373,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
fr: RegionVid,
|
||||
fr_origin: NLLRegionVariableOrigin,
|
||||
outlived_fr: RegionVid,
|
||||
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||
renctx: &mut RegionErrorNamingCtx,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
|
||||
@ -415,9 +419,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
self.report_fnmut_error(&errctx, &errci, renctx)
|
||||
}
|
||||
(ConstraintCategory::Assignment, true, false)
|
||||
| (ConstraintCategory::CallArgument, true, false) =>
|
||||
self.report_escaping_data_error(&errctx, &errci, renctx),
|
||||
_ => self.report_general_error(&errctx, &errci, renctx),
|
||||
| (ConstraintCategory::CallArgument, true, false) => {
|
||||
let mut db = self.report_escaping_data_error(&errctx, &errci, renctx);
|
||||
|
||||
outlives_suggestion.intermediate_suggestion(&errctx, &errci, renctx, &mut db);
|
||||
outlives_suggestion.collect_constraint(fr, outlived_fr);
|
||||
|
||||
db
|
||||
}
|
||||
_ => {
|
||||
let mut db = self.report_general_error(&errctx, &errci, renctx);
|
||||
|
||||
outlives_suggestion.intermediate_suggestion(&errctx, &errci, renctx, &mut db);
|
||||
outlives_suggestion.collect_constraint(fr, outlived_fr);
|
||||
|
||||
db
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,315 @@
|
||||
//! Contains utilities for generating suggestions for borrowck errors related to unsatisified
|
||||
//! outlives constraints.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use log::debug;
|
||||
use rustc::{hir::def_id::DefId, infer::InferCtxt, mir::Body, ty::RegionVid};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{Diagnostic, DiagnosticBuilder, Level};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use crate::borrow_check::nll::region_infer::{
|
||||
error_reporting::{
|
||||
region_name::{RegionName, RegionNameSource},
|
||||
ErrorConstraintInfo, ErrorReportingCtx, RegionErrorNamingCtx,
|
||||
},
|
||||
RegionInferenceContext,
|
||||
};
|
||||
|
||||
/// The different things we could suggest.
|
||||
enum SuggestedConstraint {
|
||||
/// Outlives(a, [b, c, d, ...]) => 'a: 'b + 'c + 'd + ...
|
||||
Outlives(RegionName, SmallVec<[RegionName; 2]>),
|
||||
|
||||
/// 'a = 'b
|
||||
Equal(RegionName, RegionName),
|
||||
|
||||
/// 'a: 'static i.e. 'a = 'static and the user should just use 'static
|
||||
Static(RegionName),
|
||||
}
|
||||
|
||||
/// Collects information about outlives constraints that needed to be added for a given MIR node
|
||||
/// corresponding to a function definition.
|
||||
///
|
||||
/// Adds a help note suggesting adding a where clause with the needed constraints.
|
||||
pub struct OutlivesSuggestionBuilder {
|
||||
/// The MIR DefId of the fn with the lifetime error.
|
||||
mir_def_id: DefId,
|
||||
|
||||
/// The list of outlives constraints that need to be added. Specifically, we map each free
|
||||
/// region to all other regions that it must outlive. I will use the shorthand `fr:
|
||||
/// outlived_frs`. Not all of these regions will already have names necessarily. Some could be
|
||||
/// implicit free regions that we inferred. These will need to be given names in the final
|
||||
/// suggestion message.
|
||||
constraints_to_add: BTreeMap<RegionVid, Vec<RegionVid>>,
|
||||
}
|
||||
|
||||
impl OutlivesSuggestionBuilder {
|
||||
/// Create a new builder for the given MIR node representing a fn definition.
|
||||
crate fn new(mir_def_id: DefId) -> Self {
|
||||
OutlivesSuggestionBuilder { mir_def_id, constraints_to_add: BTreeMap::default() }
|
||||
}
|
||||
|
||||
/// Returns `true` iff the `RegionNameSource` is a valid source for an outlives
|
||||
/// suggestion.
|
||||
//
|
||||
// FIXME: Currently, we only report suggestions if the `RegionNameSource` is an early-bound
|
||||
// region or a named region, avoiding using regions with synthetic names altogether. This
|
||||
// allows us to avoid giving impossible suggestions (e.g. adding bounds to closure args).
|
||||
// We can probably be less conservative, since some inferred free regions are namable (e.g.
|
||||
// the user can explicitly name them. To do this, we would allow some regions whose names
|
||||
// come from `MatchedAdtAndSegment`, being careful to filter out bad suggestions, such as
|
||||
// naming the `'self` lifetime in methods, etc.
|
||||
fn region_name_is_suggestable(name: &RegionName) -> bool {
|
||||
match name.source {
|
||||
RegionNameSource::NamedEarlyBoundRegion(..)
|
||||
| RegionNameSource::NamedFreeRegion(..)
|
||||
| RegionNameSource::Static => {
|
||||
debug!("Region {:?} is suggestable", name);
|
||||
true
|
||||
}
|
||||
|
||||
// Don't give suggestions for upvars, closure return types, or other unnamable
|
||||
// regions.
|
||||
RegionNameSource::SynthesizedFreeEnvRegion(..)
|
||||
| RegionNameSource::CannotMatchHirTy(..)
|
||||
| RegionNameSource::MatchedHirTy(..)
|
||||
| RegionNameSource::MatchedAdtAndSegment(..)
|
||||
| RegionNameSource::AnonRegionFromUpvar(..)
|
||||
| RegionNameSource::AnonRegionFromOutput(..)
|
||||
| RegionNameSource::AnonRegionFromYieldTy(..) => {
|
||||
debug!("Region {:?} is NOT suggestable", name);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`.
|
||||
fn region_vid_to_name(
|
||||
&self,
|
||||
errctx: &ErrorReportingCtx<'_, '_, '_>,
|
||||
renctx: &mut RegionErrorNamingCtx,
|
||||
region: RegionVid,
|
||||
) -> Option<RegionName> {
|
||||
errctx
|
||||
.region_infcx
|
||||
.give_region_a_name(errctx, renctx, region)
|
||||
.filter(Self::region_name_is_suggestable)
|
||||
}
|
||||
|
||||
/// Compiles a list of all suggestions to be printed in the final big suggestion.
|
||||
fn compile_all_suggestions<'tcx>(
|
||||
&self,
|
||||
body: &Body<'tcx>,
|
||||
region_infcx: &RegionInferenceContext<'tcx>,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
renctx: &mut RegionErrorNamingCtx,
|
||||
) -> SmallVec<[SuggestedConstraint; 2]> {
|
||||
let mut suggested = SmallVec::new();
|
||||
|
||||
// Keep track of variables that we have already suggested unifying so that we don't print
|
||||
// out silly duplicate messages.
|
||||
let mut unified_already = FxHashSet::default();
|
||||
|
||||
let errctx = ErrorReportingCtx {
|
||||
region_infcx,
|
||||
infcx,
|
||||
body,
|
||||
mir_def_id: self.mir_def_id,
|
||||
|
||||
// We should not be suggesting naming upvars, so we pass in a dummy set of upvars that
|
||||
// should never be used.
|
||||
upvars: &[],
|
||||
};
|
||||
|
||||
for (fr, outlived) in &self.constraints_to_add {
|
||||
let fr_name = if let Some(fr_name) = self.region_vid_to_name(&errctx, renctx, *fr) {
|
||||
fr_name
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let outlived = outlived
|
||||
.iter()
|
||||
// if there is a `None`, we will just omit that constraint
|
||||
.filter_map(|fr| {
|
||||
self.region_vid_to_name(&errctx, renctx, *fr).map(|rname| (fr, rname))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// No suggestable outlived lifetimes.
|
||||
if outlived.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// There are three types of suggestions we can make:
|
||||
// 1) Suggest a bound: 'a: 'b
|
||||
// 2) Suggest replacing 'a with 'static. If any of `outlived` is `'static`, then we
|
||||
// should just replace 'a with 'static.
|
||||
// 3) Suggest unifying 'a with 'b if we have both 'a: 'b and 'b: 'a
|
||||
|
||||
if outlived.iter().any(|(_, outlived_name)| {
|
||||
if let RegionNameSource::Static = outlived_name.source {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
suggested.push(SuggestedConstraint::Static(fr_name));
|
||||
} else {
|
||||
// We want to isolate out all lifetimes that should be unified and print out
|
||||
// separate messages for them.
|
||||
|
||||
let (unified, other): (Vec<_>, Vec<_>) = outlived.into_iter().partition(
|
||||
// Do we have both 'fr: 'r and 'r: 'fr?
|
||||
|(r, _)| {
|
||||
self.constraints_to_add
|
||||
.get(r)
|
||||
.map(|r_outlived| r_outlived.as_slice().contains(fr))
|
||||
.unwrap_or(false)
|
||||
},
|
||||
);
|
||||
|
||||
for (r, bound) in unified.into_iter() {
|
||||
if !unified_already.contains(fr) {
|
||||
suggested.push(SuggestedConstraint::Equal(fr_name.clone(), bound));
|
||||
unified_already.insert(r);
|
||||
}
|
||||
}
|
||||
|
||||
if !other.is_empty() {
|
||||
let other =
|
||||
other.iter().map(|(_, rname)| rname.clone()).collect::<SmallVec<_>>();
|
||||
suggested.push(SuggestedConstraint::Outlives(fr_name, other))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suggested
|
||||
}
|
||||
|
||||
/// Add the outlives constraint `fr: outlived_fr` to the set of constraints we need to suggest.
|
||||
crate fn collect_constraint(&mut self, fr: RegionVid, outlived_fr: RegionVid) {
|
||||
debug!("Collected {:?}: {:?}", fr, outlived_fr);
|
||||
|
||||
// Add to set of constraints for final help note.
|
||||
self.constraints_to_add.entry(fr).or_insert(Vec::new()).push(outlived_fr);
|
||||
}
|
||||
|
||||
/// Emit an intermediate note on the given `Diagnostic` if the involved regions are
|
||||
/// suggestable.
|
||||
crate fn intermediate_suggestion(
|
||||
&mut self,
|
||||
errctx: &ErrorReportingCtx<'_, '_, '_>,
|
||||
errci: &ErrorConstraintInfo,
|
||||
renctx: &mut RegionErrorNamingCtx,
|
||||
diag: &mut DiagnosticBuilder<'_>,
|
||||
) {
|
||||
// Emit an intermediate note.
|
||||
let fr_name = self.region_vid_to_name(errctx, renctx, errci.fr);
|
||||
let outlived_fr_name = self.region_vid_to_name(errctx, renctx, errci.outlived_fr);
|
||||
|
||||
if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) {
|
||||
if let RegionNameSource::Static = outlived_fr_name.source {
|
||||
diag.help(&format!("consider replacing `{}` with `'static`", fr_name));
|
||||
} else {
|
||||
diag.help(&format!(
|
||||
"consider adding the following bound: `{}: {}`",
|
||||
fr_name, outlived_fr_name
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
|
||||
/// suggestion including all collected constraints.
|
||||
crate fn add_suggestion<'tcx>(
|
||||
&self,
|
||||
body: &Body<'tcx>,
|
||||
region_infcx: &RegionInferenceContext<'tcx>,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
renctx: &mut RegionErrorNamingCtx,
|
||||
) {
|
||||
// No constraints to add? Done.
|
||||
if self.constraints_to_add.is_empty() {
|
||||
debug!("No constraints to suggest.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is only one constraint to suggest, then we already suggested it in the
|
||||
// intermediate suggestion above.
|
||||
if self.constraints_to_add.len() == 1 {
|
||||
debug!("Only 1 suggestion. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all suggestable constraints.
|
||||
let suggested = self.compile_all_suggestions(body, region_infcx, infcx, renctx);
|
||||
|
||||
// If there are no suggestable constraints...
|
||||
if suggested.is_empty() {
|
||||
debug!("Only 1 suggestable constraint. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is exactly one suggestable constraints, then just suggest it. Otherwise, emit a
|
||||
// list of diagnostics.
|
||||
let mut diag = if suggested.len() == 1 {
|
||||
DiagnosticBuilder::new(
|
||||
infcx.tcx.sess.diagnostic(),
|
||||
Level::Help,
|
||||
&match suggested.last().unwrap() {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> =
|
||||
bs.iter().map(|r| format!("{}", r)).collect();
|
||||
format!("add bound `{}: {}`", a, bs.join(" + "))
|
||||
}
|
||||
|
||||
SuggestedConstraint::Equal(a, b) => {
|
||||
format!("`{}` and `{}` must be the same: replace one with the other", a, b)
|
||||
}
|
||||
SuggestedConstraint::Static(a) => format!("replace `{}` with `'static`", a),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
// Create a new diagnostic.
|
||||
let mut diag = DiagnosticBuilder::new(
|
||||
infcx.tcx.sess.diagnostic(),
|
||||
Level::Help,
|
||||
"the following changes may resolve your lifetime errors",
|
||||
);
|
||||
|
||||
// Add suggestions.
|
||||
for constraint in suggested {
|
||||
match constraint {
|
||||
SuggestedConstraint::Outlives(a, bs) => {
|
||||
let bs: SmallVec<[String; 2]> =
|
||||
bs.iter().map(|r| format!("{}", r)).collect();
|
||||
diag.help(&format!("add bound `{}: {}`", a, bs.join(" + ")));
|
||||
}
|
||||
SuggestedConstraint::Equal(a, b) => {
|
||||
diag.help(&format!(
|
||||
"`{}` and `{}` must be the same: replace one with the other",
|
||||
a, b
|
||||
));
|
||||
}
|
||||
SuggestedConstraint::Static(a) => {
|
||||
diag.help(&format!("replace `{}` with `'static`", a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
diag
|
||||
};
|
||||
|
||||
// We want this message to appear after other messages on the mir def.
|
||||
let mir_span = infcx.tcx.def_span(self.mir_def_id);
|
||||
diag.sort_span = mir_span.shrink_to_hi();
|
||||
|
||||
// Buffer the diagnostic
|
||||
diag.buffer(errors_buffer);
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ use crate::borrow_check::nll::{
|
||||
region_infer::values::{
|
||||
PlaceholderIndices, RegionElement, ToElementIndex
|
||||
},
|
||||
region_infer::error_reporting::outlives_suggestion::OutlivesSuggestionBuilder,
|
||||
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
||||
};
|
||||
use crate::borrow_check::Upvar;
|
||||
@ -1326,6 +1327,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
region_naming: &mut RegionErrorNamingCtx,
|
||||
) {
|
||||
let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id);
|
||||
|
||||
for (fr, fr_definition) in self.definitions.iter_enumerated() {
|
||||
match fr_definition.origin {
|
||||
NLLRegionVariableOrigin::FreeRegion => {
|
||||
@ -1339,6 +1342,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
mir_def_id,
|
||||
fr,
|
||||
&mut propagated_outlives_requirements,
|
||||
&mut outlives_suggestion,
|
||||
errors_buffer,
|
||||
region_naming,
|
||||
);
|
||||
@ -1353,6 +1357,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit outlives suggestions
|
||||
outlives_suggestion.add_suggestion(body, self, infcx, errors_buffer, region_naming);
|
||||
}
|
||||
|
||||
/// Checks the final value for the free region `fr` to see if it
|
||||
@ -1371,6 +1378,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
mir_def_id: DefId,
|
||||
longer_fr: RegionVid,
|
||||
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
||||
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
region_naming: &mut RegionErrorNamingCtx,
|
||||
) {
|
||||
@ -1399,6 +1407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
upvars,
|
||||
mir_def_id,
|
||||
propagated_outlives_requirements,
|
||||
outlives_suggestion,
|
||||
errors_buffer,
|
||||
region_naming,
|
||||
);
|
||||
@ -1416,6 +1425,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
upvars,
|
||||
mir_def_id,
|
||||
propagated_outlives_requirements,
|
||||
outlives_suggestion,
|
||||
errors_buffer,
|
||||
region_naming,
|
||||
) {
|
||||
@ -1438,6 +1448,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
||||
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
region_naming: &mut RegionErrorNamingCtx,
|
||||
) -> Option<ErrorReported> {
|
||||
@ -1497,6 +1508,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
longer_fr,
|
||||
NLLRegionVariableOrigin::FreeRegion,
|
||||
shorter_fr,
|
||||
outlives_suggestion,
|
||||
region_naming,
|
||||
);
|
||||
|
||||
|
@ -43,5 +43,9 @@ LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
LL | demand_y(x, y, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -46,5 +46,9 @@ LL | | demand_y(x, y, x.get())
|
||||
LL | | });
|
||||
| |______^ `cell_a` escapes the function body here
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -46,5 +46,9 @@ LL | | demand_y(x, y, x.get())
|
||||
LL | | });
|
||||
| |______^ `cell_a` escapes the function body here
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -43,5 +43,9 @@ LL | fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
|
||||
LL | demand_y(outlives1, outlives2, x.get())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,5 +6,9 @@ LL | fn foo<'a>(x: &'a u32) -> &'static u32 {
|
||||
LL | &*x
|
||||
| ^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,5 +8,9 @@ LL | fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'b u32 {
|
||||
LL | &*x
|
||||
| ^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,5 +9,9 @@ LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> i
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,6 +7,10 @@ LL | fn foo<'a>(x: i32) {
|
||||
LL | A::<'a>::X..=A::<'static>::X => (),
|
||||
| ^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-58299.rs:24:27
|
||||
|
|
||||
@ -16,5 +20,9 @@ LL | fn bar<'a>(x: i32) {
|
||||
LL | A::<'static>::X..=A::<'a>::X => (),
|
||||
| ^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -9,5 +9,9 @@ LL | let g: fn(_, _) -> _ = |_x, y| y;
|
||||
LL | g
|
||||
| ^ returning this value requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,5 +7,9 @@ LL | fn bar<'a>(x: &'a u32) -> &'static u32 {
|
||||
LL | f(x)
|
||||
| ^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,5 +7,9 @@ LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
|
||||
LL | unsafe { g(input) }
|
||||
| ^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,5 +6,9 @@ LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
77
src/test/ui/nll/outlives-suggestion-simple.rs
Normal file
77
src/test/ui/nll/outlives-suggestion-simple.rs
Normal file
@ -0,0 +1,77 @@
|
||||
// Test the simplest of outlives suggestions.
|
||||
|
||||
#![feature(nll)]
|
||||
|
||||
fn foo1<'a, 'b>(x: &'a usize) -> &'b usize {
|
||||
x //~ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn foo2<'a>(x: &'a usize) -> &'static usize {
|
||||
x //~ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) {
|
||||
(x, y) //~ERROR lifetime may not live long enough
|
||||
//~^ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) {
|
||||
// FIXME: ideally, we suggest 'a: 'b + 'c, but as of today (may 04, 2019), the null error
|
||||
// reporting stops after the first error in a MIR def so as not to produce too many errors, so
|
||||
// currently we only report 'a: 'b. The user would then re-run and get another error.
|
||||
(x, x) //~ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
struct Foo<'a> {
|
||||
x: &'a usize,
|
||||
}
|
||||
|
||||
impl Foo<'static> {
|
||||
pub fn foo<'a>(x: &'a usize) -> Self {
|
||||
Foo { x } //~ERROR lifetime may not live long enough
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar<'a> {
|
||||
x: &'a usize,
|
||||
}
|
||||
|
||||
impl<'a> Bar<'a> {
|
||||
pub fn get<'b>(&self) -> &'b usize {
|
||||
self.x //~ERROR lifetime may not live long enough
|
||||
}
|
||||
}
|
||||
|
||||
// source: https://stackoverflow.com/questions/41417057/why-do-i-get-a-lifetime-error-when-i-use-a-mutable-reference-in-a-struct-instead
|
||||
struct Baz<'a> {
|
||||
x: &'a mut i32,
|
||||
}
|
||||
|
||||
impl<'a> Baz<'a> {
|
||||
fn get<'b>(&'b self) -> &'a i32 {
|
||||
self.x //~ERROR lifetime may not live long enough
|
||||
}
|
||||
}
|
||||
|
||||
// source: https://stackoverflow.com/questions/41204134/rust-lifetime-error
|
||||
struct Bar2<'a> {
|
||||
bar: &'a str,
|
||||
}
|
||||
impl<'a> Bar2<'a> {
|
||||
fn new(foo: &'a Foo2<'a>) -> Bar2<'a> {
|
||||
Bar2 { bar: foo.raw }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Foo2<'a> {
|
||||
raw: &'a str,
|
||||
cell: std::cell::Cell<&'a str>,
|
||||
}
|
||||
impl<'a> Foo2<'a> {
|
||||
// should not produce outlives suggestions to name 'self
|
||||
fn get_bar(&self) -> Bar2 {
|
||||
Bar2::new(&self) //~ERROR borrowed data escapes outside of function
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
118
src/test/ui/nll/outlives-suggestion-simple.stderr
Normal file
118
src/test/ui/nll/outlives-suggestion-simple.stderr
Normal file
@ -0,0 +1,118 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:6:5
|
||||
|
|
||||
LL | fn foo1<'a, 'b>(x: &'a usize) -> &'b usize {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:10:5
|
||||
|
|
||||
LL | fn foo2<'a>(x: &'a usize) -> &'static usize {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:14:5
|
||||
|
|
||||
LL | fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | (x, y)
|
||||
| ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:14:5
|
||||
|
|
||||
LL | fn foo3<'a, 'b>(x: &'a usize, y: &'b usize) -> (&'b usize, &'a usize) {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
LL | (x, y)
|
||||
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: `'a` and `'b` must be the same; replace one with the other
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:22:5
|
||||
|
|
||||
LL | fn foo4<'a, 'b, 'c>(x: &'a usize) -> (&'b usize, &'c usize) {
|
||||
| -- -- lifetime `'b` defined here
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
...
|
||||
LL | (x, x)
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:31:9
|
||||
|
|
||||
LL | pub fn foo<'a>(x: &'a usize) -> Self {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | Foo { x }
|
||||
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:41:9
|
||||
|
|
||||
LL | impl<'a> Bar<'a> {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | pub fn get<'b>(&self) -> &'b usize {
|
||||
| -- lifetime `'b` defined here
|
||||
LL | self.x
|
||||
| ^^^^^^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/outlives-suggestion-simple.rs:52:9
|
||||
|
|
||||
LL | impl<'a> Baz<'a> {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | fn get<'b>(&'b self) -> &'a i32 {
|
||||
| -- lifetime `'b` defined here
|
||||
LL | self.x
|
||||
| ^^^^^^ returning this value requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error[E0521]: borrowed data escapes outside of function
|
||||
--> $DIR/outlives-suggestion-simple.rs:73:9
|
||||
|
|
||||
LL | fn get_bar(&self) -> Bar2 {
|
||||
| -----
|
||||
| |
|
||||
| `self` is declared here, outside of the function body
|
||||
| `self` is a reference that is only valid in the function body
|
||||
LL | Bar2::new(&self)
|
||||
| ^^^^^^^^^^^^^^^^ `self` escapes the function body here
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
@ -51,6 +51,10 @@ LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/projection-one-region-closure.rs:56:29
|
||||
|
|
||||
@ -105,6 +109,10 @@ LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/projection-one-region-closure.rs:70:29
|
||||
|
|
||||
|
@ -42,6 +42,10 @@ LL | fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/projection-one-region-trait-bound-closure.rs:47:29
|
||||
|
|
||||
@ -87,6 +91,10 @@ LL | fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/projection-one-region-trait-bound-closure.rs:60:29
|
||||
|
|
||||
|
@ -237,6 +237,10 @@ LL | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T)
|
||||
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
note: External requirements
|
||||
--> $DIR/projection-two-region-trait-bound-closure.rs:97:29
|
||||
|
|
||||
|
@ -7,6 +7,10 @@ LL | return;
|
||||
LL | let x: &'static &'a ();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:13:12
|
||||
|
|
||||
@ -16,6 +20,10 @@ LL | return;
|
||||
LL | let x: &'static &'a () = &&();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:17:12
|
||||
|
|
||||
@ -24,6 +32,10 @@ LL | fn uninit_infer<'a>() {
|
||||
LL | let x: &'static &'a _;
|
||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:23:12
|
||||
|
|
||||
@ -33,6 +45,10 @@ LL | return;
|
||||
LL | let x: &'static &'a _ = &&();
|
||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:28:12
|
||||
|
|
||||
@ -42,6 +58,10 @@ LL | return;
|
||||
LL | let _: &'static &'a ();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:33:12
|
||||
|
|
||||
@ -51,6 +71,10 @@ LL | return;
|
||||
LL | let _: &'static &'a () = &&();
|
||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:38:12
|
||||
|
|
||||
@ -60,6 +84,10 @@ LL | return;
|
||||
LL | let _: &'static &'a _ = &&();
|
||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/wf-unreachable.rs:51:12
|
||||
|
|
||||
@ -69,5 +97,9 @@ LL | return;
|
||||
LL | let _: C<'static, 'a, _> = C((), &(), &());
|
||||
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -8,6 +8,10 @@ LL | fn shared_to_const<'a, 'b>(x: &&'a i32) -> *const &'b i32 {
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-coercions.rs:8:5
|
||||
|
|
||||
@ -18,6 +22,10 @@ LL | fn unique_to_const<'a, 'b>(x: &mut &'a i32) -> *const &'b i32 {
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-coercions.rs:13:5
|
||||
|
|
||||
@ -40,6 +48,10 @@ LL | // Two errors because *mut is invariant
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: `'b` and `'a` must be the same; replace one with the other
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-coercions.rs:18:5
|
||||
|
|
||||
@ -50,6 +62,10 @@ LL | fn mut_to_const<'a, 'b>(x: *mut &'a i32) -> *const &'b i32 {
|
||||
LL | x
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-coercions.rs:24:5
|
||||
|
|
||||
@ -61,6 +77,10 @@ LL | fn array_elem<'a, 'b>(x: &'a i32) -> *const &'b i32 {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-coercions.rs:30:5
|
||||
|
|
||||
@ -72,6 +92,10 @@ LL | fn array_coerce<'a, 'b>(x: &'a i32) -> *const [&'b i32; 3] {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-coercions.rs:36:5
|
||||
|
|
||||
@ -83,5 +107,9 @@ LL | fn nested_array<'a, 'b>(x: &'a i32) -> *const [&'b i32; 2] {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
@ -18,6 +18,10 @@ LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
|
||||
LL | x == y;
|
||||
| ^ requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: `'b` and `'a` must be the same; replace one with the other
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-comparisons.rs:12:5
|
||||
|
|
||||
@ -38,6 +42,10 @@ LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
|
||||
LL | x == y;
|
||||
| ^ requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: `'a` and `'b` must be the same; replace one with the other
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/type-check-pointer-comparisons.rs:18:5
|
||||
|
|
||||
@ -58,5 +66,9 @@ LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32
|
||||
LL | f == g;
|
||||
| ^ requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: `'a` and `'b` must be the same; replace one with the other
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -7,6 +7,10 @@ LL | fn foo<'a>() {
|
||||
LL | return x;
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/closure-substs.rs:15:16
|
||||
|
|
||||
@ -24,6 +28,10 @@ LL | fn bar<'a>() {
|
||||
LL | b(x);
|
||||
| ^^^^ argument requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error[E0521]: borrowed data escapes outside of closure
|
||||
--> $DIR/closure-substs.rs:29:9
|
||||
|
|
||||
|
@ -6,5 +6,9 @@ LL | fn non_wf_associated_const<'a>(x: i32) {
|
||||
LL | A::<'a>::IC;
|
||||
| ^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -16,5 +16,9 @@ LL | fn test<'a>() {
|
||||
LL | let _:fn(&()) = |_:&'a ()| {};
|
||||
| ^ requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -7,6 +7,10 @@ LL | fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-55748-pat-types-constrain-bindings.rs:49:5
|
||||
|
|
||||
@ -16,6 +20,10 @@ LL | fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-55748-pat-types-constrain-bindings.rs:62:5
|
||||
|
|
||||
@ -25,5 +33,9 @@ LL | fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -7,6 +7,10 @@ LL | let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,);
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-57731-ascibed-coupled-types.rs:22:5
|
||||
|
|
||||
@ -16,6 +20,10 @@ LL | let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,);
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-57731-ascibed-coupled-types.rs:32:5
|
||||
|
|
||||
@ -25,6 +33,10 @@ LL | let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,);
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-57731-ascibed-coupled-types.rs:37:5
|
||||
|
|
||||
@ -34,5 +46,9 @@ LL | let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,);
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -157,6 +157,10 @@ LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:125:5
|
||||
|
|
||||
@ -166,6 +170,10 @@ LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 {
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:130:5
|
||||
|
|
||||
@ -175,6 +183,10 @@ LL | let Single { value: y }: Single<&'a u32> = Single { value: &22 };
|
||||
LL | y
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/patterns.rs:134:18
|
||||
|
|
||||
@ -183,6 +195,10 @@ LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 {
|
||||
LL | let (y, _z): (&'static u32, u32) = (x, 44);
|
||||
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error: aborting due to 19 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0597, E0716.
|
||||
|
@ -8,5 +8,9 @@ LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
|
||||
LL | Foo::xmute(u)
|
||||
| ^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,5 +8,9 @@ LL | fn bar<'a, 'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
|
||||
LL | foo(x, y)
|
||||
| ^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,5 +8,9 @@ LL | fn bar<'a, 'b>(x: Cell<&'a u32>, y: Cell<&'b u32>) {
|
||||
LL | Foo { x, y };
|
||||
| ^ requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,5 +9,9 @@ LL | fn with_assoc<'a,'b>() {
|
||||
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,10 @@ LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||
LL | let z: Option<&'b &'a usize> = None;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/regions-free-region-ordering-caller.rs:17:12
|
||||
|
|
||||
@ -19,6 +23,10 @@ LL | let y: Paramd<'a> = Paramd { x: a };
|
||||
LL | let z: Option<&'b Paramd<'a>> = None;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
||||
|
|
||||
@ -29,5 +37,9 @@ LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
|
||||
LL | let z: Option<&'a &'b usize> = None;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -9,6 +9,10 @@ LL | fn with_assoc<'a,'b>() {
|
||||
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
|
||||
|
|
||||
@ -20,5 +24,9 @@ LL | fn with_assoc_sub<'a,'b>() {
|
||||
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -9,5 +9,9 @@ LL | fn with_assoc<'a,'b>() {
|
||||
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: add bound `'b: 'a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,6 +6,10 @@ LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
|
||||
LL | t
|
||||
| ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
||||
help: the following changes may resolve your lifetime errors
|
||||
|
|
||||
= help: replace `'a` with `'static`
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `u`
|
||||
--> $DIR/regions-static-bound.rs:14:5
|
||||
|
|
||||
|
Loading…
x
Reference in New Issue
Block a user