implement outlive suggestions
This commit is contained in:
parent
b7176b44a2
commit
3a1847b07d
39 changed files with 807 additions and 6 deletions
|
@ -6,7 +6,7 @@ use crate::Applicability;
|
||||||
use crate::Level;
|
use crate::Level;
|
||||||
use crate::snippet::Style;
|
use crate::snippet::Style;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use syntax_pos::{MultiSpan, Span};
|
use syntax_pos::{MultiSpan, Span, DUMMY_SP};
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
|
#[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
|
||||||
|
@ -17,6 +17,11 @@ pub struct Diagnostic {
|
||||||
pub span: MultiSpan,
|
pub span: MultiSpan,
|
||||||
pub children: Vec<SubDiagnostic>,
|
pub children: Vec<SubDiagnostic>,
|
||||||
pub suggestions: Vec<CodeSuggestion>,
|
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)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||||
|
@ -87,6 +92,7 @@ impl Diagnostic {
|
||||||
span: MultiSpan::new(),
|
span: MultiSpan::new(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
suggestions: vec![],
|
suggestions: vec![],
|
||||||
|
sort_span: DUMMY_SP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +124,11 @@ impl Diagnostic {
|
||||||
self.level == Level::Cancelled
|
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.
|
/// 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
|
/// 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.
|
/// 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 {
|
pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
|
||||||
self.span = sp.into();
|
self.span = sp.into();
|
||||||
|
if let Some(span) = self.span.primary_span() {
|
||||||
|
self.sort_span = span;
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,7 +367,7 @@ fn do_mir_borrowck<'a, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mbcx.errors_buffer.is_empty() {
|
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(..) {
|
for diag in mbcx.errors_buffer.drain(..) {
|
||||||
mbcx.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag);
|
mbcx.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag);
|
||||||
|
|
|
@ -18,6 +18,10 @@ use syntax::errors::Applicability;
|
||||||
use syntax::symbol::kw;
|
use syntax::symbol::kw;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
|
use self::outlives_suggestion::OutlivesSuggestionBuilder;
|
||||||
|
|
||||||
|
pub mod outlives_suggestion;
|
||||||
|
|
||||||
mod region_name;
|
mod region_name;
|
||||||
mod var_name;
|
mod var_name;
|
||||||
|
|
||||||
|
@ -56,7 +60,6 @@ enum Trace {
|
||||||
/// Various pieces of state used when reporting borrow checker errors.
|
/// Various pieces of state used when reporting borrow checker errors.
|
||||||
pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
|
pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
|
||||||
/// The region inference context used for borrow chekcing this MIR body.
|
/// 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>,
|
region_infcx: &'b RegionInferenceContext<'tcx>,
|
||||||
|
|
||||||
/// The inference context used for type checking.
|
/// The inference context used for type checking.
|
||||||
|
@ -370,6 +373,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
fr: RegionVid,
|
fr: RegionVid,
|
||||||
fr_origin: NLLRegionVariableOrigin,
|
fr_origin: NLLRegionVariableOrigin,
|
||||||
outlived_fr: RegionVid,
|
outlived_fr: RegionVid,
|
||||||
|
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||||
renctx: &mut RegionErrorNamingCtx,
|
renctx: &mut RegionErrorNamingCtx,
|
||||||
) -> DiagnosticBuilder<'a> {
|
) -> DiagnosticBuilder<'a> {
|
||||||
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
|
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
|
||||||
|
@ -415,9 +419,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
self.report_fnmut_error(&errctx, &errci, renctx)
|
self.report_fnmut_error(&errctx, &errci, renctx)
|
||||||
}
|
}
|
||||||
(ConstraintCategory::Assignment, true, false)
|
(ConstraintCategory::Assignment, true, false)
|
||||||
| (ConstraintCategory::CallArgument, true, false) =>
|
| (ConstraintCategory::CallArgument, true, false) => {
|
||||||
self.report_escaping_data_error(&errctx, &errci, renctx),
|
let mut db = self.report_escaping_data_error(&errctx, &errci, renctx);
|
||||||
_ => self.report_general_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::{
|
region_infer::values::{
|
||||||
PlaceholderIndices, RegionElement, ToElementIndex
|
PlaceholderIndices, RegionElement, ToElementIndex
|
||||||
},
|
},
|
||||||
|
region_infer::error_reporting::outlives_suggestion::OutlivesSuggestionBuilder,
|
||||||
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
type_check::{free_region_relations::UniversalRegionRelations, Locations},
|
||||||
};
|
};
|
||||||
use crate::borrow_check::Upvar;
|
use crate::borrow_check::Upvar;
|
||||||
|
@ -1326,6 +1327,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
errors_buffer: &mut Vec<Diagnostic>,
|
errors_buffer: &mut Vec<Diagnostic>,
|
||||||
region_naming: &mut RegionErrorNamingCtx,
|
region_naming: &mut RegionErrorNamingCtx,
|
||||||
) {
|
) {
|
||||||
|
let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id);
|
||||||
|
|
||||||
for (fr, fr_definition) in self.definitions.iter_enumerated() {
|
for (fr, fr_definition) in self.definitions.iter_enumerated() {
|
||||||
match fr_definition.origin {
|
match fr_definition.origin {
|
||||||
NLLRegionVariableOrigin::FreeRegion => {
|
NLLRegionVariableOrigin::FreeRegion => {
|
||||||
|
@ -1339,6 +1342,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
mir_def_id,
|
mir_def_id,
|
||||||
fr,
|
fr,
|
||||||
&mut propagated_outlives_requirements,
|
&mut propagated_outlives_requirements,
|
||||||
|
&mut outlives_suggestion,
|
||||||
errors_buffer,
|
errors_buffer,
|
||||||
region_naming,
|
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
|
/// 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,
|
mir_def_id: DefId,
|
||||||
longer_fr: RegionVid,
|
longer_fr: RegionVid,
|
||||||
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
||||||
|
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||||
errors_buffer: &mut Vec<Diagnostic>,
|
errors_buffer: &mut Vec<Diagnostic>,
|
||||||
region_naming: &mut RegionErrorNamingCtx,
|
region_naming: &mut RegionErrorNamingCtx,
|
||||||
) {
|
) {
|
||||||
|
@ -1399,6 +1407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
upvars,
|
upvars,
|
||||||
mir_def_id,
|
mir_def_id,
|
||||||
propagated_outlives_requirements,
|
propagated_outlives_requirements,
|
||||||
|
outlives_suggestion,
|
||||||
errors_buffer,
|
errors_buffer,
|
||||||
region_naming,
|
region_naming,
|
||||||
);
|
);
|
||||||
|
@ -1416,6 +1425,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
upvars,
|
upvars,
|
||||||
mir_def_id,
|
mir_def_id,
|
||||||
propagated_outlives_requirements,
|
propagated_outlives_requirements,
|
||||||
|
outlives_suggestion,
|
||||||
errors_buffer,
|
errors_buffer,
|
||||||
region_naming,
|
region_naming,
|
||||||
) {
|
) {
|
||||||
|
@ -1438,6 +1448,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
upvars: &[Upvar],
|
upvars: &[Upvar],
|
||||||
mir_def_id: DefId,
|
mir_def_id: DefId,
|
||||||
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
|
||||||
|
outlives_suggestion: &mut OutlivesSuggestionBuilder,
|
||||||
errors_buffer: &mut Vec<Diagnostic>,
|
errors_buffer: &mut Vec<Diagnostic>,
|
||||||
region_naming: &mut RegionErrorNamingCtx,
|
region_naming: &mut RegionErrorNamingCtx,
|
||||||
) -> Option<ErrorReported> {
|
) -> Option<ErrorReported> {
|
||||||
|
@ -1497,6 +1508,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
longer_fr,
|
longer_fr,
|
||||||
NLLRegionVariableOrigin::FreeRegion,
|
NLLRegionVariableOrigin::FreeRegion,
|
||||||
shorter_fr,
|
shorter_fr,
|
||||||
|
outlives_suggestion,
|
||||||
region_naming,
|
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())
|
LL | demand_y(x, y, x.get())
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -46,5 +46,9 @@ LL | | demand_y(x, y, x.get())
|
||||||
LL | | });
|
LL | | });
|
||||||
| |______^ `cell_a` escapes the function body here
|
| |______^ `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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -46,5 +46,9 @@ LL | | demand_y(x, y, x.get())
|
||||||
LL | | });
|
LL | | });
|
||||||
| |______^ `cell_a` escapes the function body here
|
| |______^ `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
|
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())
|
LL | demand_y(outlives1, outlives2, x.get())
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -6,5 +6,9 @@ LL | fn foo<'a>(x: &'a u32) -> &'static u32 {
|
||||||
LL | &*x
|
LL | &*x
|
||||||
| ^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^ 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
|
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
|
LL | &*x
|
||||||
| ^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
| ^^^ 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
|
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
|
LL | x
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ LL | fn foo<'a>(x: i32) {
|
||||||
LL | A::<'a>::X..=A::<'static>::X => (),
|
LL | A::<'a>::X..=A::<'static>::X => (),
|
||||||
| ^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-58299.rs:24:27
|
--> $DIR/issue-58299.rs:24:27
|
||||||
|
|
|
|
||||||
|
@ -16,5 +20,9 @@ LL | fn bar<'a>(x: i32) {
|
||||||
LL | A::<'static>::X..=A::<'a>::X => (),
|
LL | A::<'static>::X..=A::<'a>::X => (),
|
||||||
| ^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^ 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
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,9 @@ LL | let g: fn(_, _) -> _ = |_x, y| y;
|
||||||
LL | g
|
LL | g
|
||||||
| ^ returning this value requires that `'b` must outlive `'a`
|
| ^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,9 @@ LL | fn bar<'a>(x: &'a u32) -> &'static u32 {
|
||||||
LL | f(x)
|
LL | f(x)
|
||||||
| ^^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^^ 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
|
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) }
|
LL | unsafe { g(input) }
|
||||||
| ^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
| ^^^^^^^^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -6,5 +6,9 @@ LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug {
|
||||||
LL | x
|
LL | x
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
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));
|
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: the following changes may resolve your lifetime errors
|
||||||
|
|
|
||||||
|
= help: add 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
|
||||||
|
|
|
|
||||||
|
@ -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));
|
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: the following changes may resolve your lifetime errors
|
||||||
|
|
|
||||||
|
= help: add 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
|
||||||
|
|
|
|
||||||
|
|
|
@ -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));
|
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: the following changes may resolve your lifetime errors
|
||||||
|
|
|
||||||
|
= help: add bound `'b: 'a`
|
||||||
|
|
||||||
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
|
||||||
|
|
|
|
||||||
|
@ -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));
|
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: the following changes may resolve your lifetime errors
|
||||||
|
|
|
||||||
|
= help: add bound `'b: 'a`
|
||||||
|
|
||||||
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
|
||||||
|
|
|
|
||||||
|
|
|
@ -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));
|
LL | with_signature(cell, t, |cell, t| require(cell, t));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ closure body requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
note: External requirements
|
||||||
--> $DIR/projection-two-region-trait-bound-closure.rs:97:29
|
--> $DIR/projection-two-region-trait-bound-closure.rs:97:29
|
||||||
|
|
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ LL | return;
|
||||||
LL | let x: &'static &'a ();
|
LL | let x: &'static &'a ();
|
||||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:13:12
|
--> $DIR/wf-unreachable.rs:13:12
|
||||||
|
|
|
|
||||||
|
@ -16,6 +20,10 @@ LL | return;
|
||||||
LL | let x: &'static &'a () = &&();
|
LL | let x: &'static &'a () = &&();
|
||||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:17:12
|
--> $DIR/wf-unreachable.rs:17:12
|
||||||
|
|
|
|
||||||
|
@ -24,6 +32,10 @@ LL | fn uninit_infer<'a>() {
|
||||||
LL | let x: &'static &'a _;
|
LL | let x: &'static &'a _;
|
||||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:23:12
|
--> $DIR/wf-unreachable.rs:23:12
|
||||||
|
|
|
|
||||||
|
@ -33,6 +45,10 @@ LL | return;
|
||||||
LL | let x: &'static &'a _ = &&();
|
LL | let x: &'static &'a _ = &&();
|
||||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:28:12
|
--> $DIR/wf-unreachable.rs:28:12
|
||||||
|
|
|
|
||||||
|
@ -42,6 +58,10 @@ LL | return;
|
||||||
LL | let _: &'static &'a ();
|
LL | let _: &'static &'a ();
|
||||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:33:12
|
--> $DIR/wf-unreachable.rs:33:12
|
||||||
|
|
|
|
||||||
|
@ -51,6 +71,10 @@ LL | return;
|
||||||
LL | let _: &'static &'a () = &&();
|
LL | let _: &'static &'a () = &&();
|
||||||
| ^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:38:12
|
--> $DIR/wf-unreachable.rs:38:12
|
||||||
|
|
|
|
||||||
|
@ -60,6 +84,10 @@ LL | return;
|
||||||
LL | let _: &'static &'a _ = &&();
|
LL | let _: &'static &'a _ = &&();
|
||||||
| ^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/wf-unreachable.rs:51:12
|
--> $DIR/wf-unreachable.rs:51:12
|
||||||
|
|
|
|
||||||
|
@ -69,5 +97,9 @@ LL | return;
|
||||||
LL | let _: C<'static, 'a, _> = C((), &(), &());
|
LL | let _: C<'static, 'a, _> = C((), &(), &());
|
||||||
| ^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^ 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
|
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
|
LL | x
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-coercions.rs:8:5
|
--> $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
|
LL | x
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-coercions.rs:13:5
|
--> $DIR/type-check-pointer-coercions.rs:13:5
|
||||||
|
|
|
|
||||||
|
@ -40,6 +48,10 @@ LL | // Two errors because *mut is invariant
|
||||||
LL | x
|
LL | x
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-coercions.rs:18:5
|
--> $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
|
LL | x
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-coercions.rs:24:5
|
--> $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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-coercions.rs:30:5
|
--> $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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-coercions.rs:36:5
|
--> $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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'b`
|
| ^ 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
|
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;
|
LL | x == y;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-comparisons.rs:12:5
|
--> $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;
|
LL | x == y;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/type-check-pointer-comparisons.rs:18:5
|
--> $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;
|
LL | f == g;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^ 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
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ LL | fn foo<'a>() {
|
||||||
LL | return x;
|
LL | return x;
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/closure-substs.rs:15:16
|
--> $DIR/closure-substs.rs:15:16
|
||||||
|
|
|
|
||||||
|
@ -24,6 +28,10 @@ LL | fn bar<'a>() {
|
||||||
LL | b(x);
|
LL | b(x);
|
||||||
| ^^^^ argument requires that `'a` must outlive `'static`
|
| ^^^^ 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
|
error[E0521]: borrowed data escapes outside of closure
|
||||||
--> $DIR/closure-substs.rs:29:9
|
--> $DIR/closure-substs.rs:29:9
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,5 +6,9 @@ LL | fn non_wf_associated_const<'a>(x: i32) {
|
||||||
LL | A::<'a>::IC;
|
LL | A::<'a>::IC;
|
||||||
| ^^^^^^^^^^^ requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,9 @@ LL | fn test<'a>() {
|
||||||
LL | let _:fn(&()) = |_:&'a ()| {};
|
LL | let _:fn(&()) = |_:&'a ()| {};
|
||||||
| ^ requires that `'a` must outlive `'static`
|
| ^ 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
|
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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-55748-pat-types-constrain-bindings.rs:49:5
|
--> $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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-55748-pat-types-constrain-bindings.rs:62:5
|
--> $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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ LL | let ((y, _z),) = ((s, _x),): (PairCoupledTypes<_>,);
|
||||||
LL | y
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-57731-ascibed-coupled-types.rs:22:5
|
--> $DIR/issue-57731-ascibed-coupled-types.rs:22:5
|
||||||
|
|
|
|
||||||
|
@ -16,6 +20,10 @@ LL | let ((y, _z),) = ((s, _x),): (PairCoupledRegions<_>,);
|
||||||
LL | y
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-57731-ascibed-coupled-types.rs:32:5
|
--> $DIR/issue-57731-ascibed-coupled-types.rs:32:5
|
||||||
|
|
|
|
||||||
|
@ -25,6 +33,10 @@ LL | let ((y, _z),) = ((s, _x),) as (PairCoupledTypes<_>,);
|
||||||
LL | y
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-57731-ascibed-coupled-types.rs:37:5
|
--> $DIR/issue-57731-ascibed-coupled-types.rs:37:5
|
||||||
|
|
|
|
||||||
|
@ -34,5 +46,9 @@ LL | let ((y, _z),) = ((s, _x),) as (PairCoupledRegions<_>,);
|
||||||
LL | y
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:125:5
|
--> $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
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:130:5
|
--> $DIR/patterns.rs:130:5
|
||||||
|
|
|
|
||||||
|
@ -175,6 +183,10 @@ LL | let Single { value: y }: Single<&'a u32> = Single { value: &22 };
|
||||||
LL | y
|
LL | y
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/patterns.rs:134:18
|
--> $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);
|
LL | let (y, _z): (&'static u32, u32) = (x, 44);
|
||||||
| ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^ 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
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0597, E0716.
|
Some errors have detailed explanations: E0597, E0716.
|
||||||
|
|
|
@ -8,5 +8,9 @@ LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
|
||||||
LL | Foo::xmute(u)
|
LL | Foo::xmute(u)
|
||||||
| ^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^ 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
|
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)
|
LL | foo(x, y)
|
||||||
| ^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
| ^^^^^^^^^ 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
|
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 };
|
LL | Foo { x, y };
|
||||||
| ^ requires that `'a` must outlive `'b`
|
| ^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,9 @@ LL | fn with_assoc<'a,'b>() {
|
||||||
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
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;
|
LL | let z: Option<&'b &'a usize> = None;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/regions-free-region-ordering-caller.rs:17:12
|
--> $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;
|
LL | let z: Option<&'b Paramd<'a>> = None;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
--> $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;
|
LL | let z: Option<&'a &'b usize> = None;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^ 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
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ LL | fn with_assoc<'a,'b>() {
|
||||||
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
|
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
error: lifetime may not live long enough
|
||||||
--> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
|
--> $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 { };
|
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,9 @@ LL | fn with_assoc<'a,'b>() {
|
||||||
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
|
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
|
LL | t
|
||||||
| ^ returning this value requires that `'a` must outlive `'static`
|
| ^ 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`
|
error[E0621]: explicit lifetime required in the type of `u`
|
||||||
--> $DIR/regions-static-bound.rs:14:5
|
--> $DIR/regions-static-bound.rs:14:5
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue