find and highlight the &
or '_
in region_name
This commit is contained in:
parent
9fd3d7899a
commit
a6adb1ebff
@ -402,6 +402,15 @@ pub enum GenericArg {
|
|||||||
Type(Ty),
|
Type(Ty),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl GenericArg {
|
||||||
|
pub fn span(&self) -> Span {
|
||||||
|
match self {
|
||||||
|
GenericArg::Lifetime(l) => l.span,
|
||||||
|
GenericArg::Type(t) => t.span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
pub struct GenericArgs {
|
pub struct GenericArgs {
|
||||||
/// The generic arguments for this path segment.
|
/// The generic arguments for this path segment.
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
|
|
||||||
use borrow_check::nll::region_infer::RegionInferenceContext;
|
use borrow_check::nll::region_infer::RegionInferenceContext;
|
||||||
use borrow_check::nll::ToRegionVid;
|
use borrow_check::nll::ToRegionVid;
|
||||||
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::{Local, Mir};
|
use rustc::mir::{Local, Mir};
|
||||||
use rustc::ty::{self, RegionVid, TyCtxt};
|
use rustc::ty::subst::{Substs, UnpackedKind};
|
||||||
|
use rustc::ty::{self, RegionVid, Ty, TyCtxt};
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use rustc_errors::DiagnosticBuilder;
|
use rustc_errors::DiagnosticBuilder;
|
||||||
use syntax::ast::Name;
|
use syntax::ast::Name;
|
||||||
@ -60,7 +62,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
|
|
||||||
self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag)
|
self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag)
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.give_name_if_anonymous_region_appears_in_arguments(tcx, mir, fr, counter, diag)
|
self.give_name_if_anonymous_region_appears_in_arguments(
|
||||||
|
tcx, mir, mir_def_id, fr, counter, diag,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.give_name_if_anonymous_region_appears_in_upvars(tcx, mir, fr, counter, diag)
|
self.give_name_if_anonymous_region_appears_in_upvars(tcx, mir, fr, counter, diag)
|
||||||
@ -129,20 +133,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
|
mir_def_id: DefId,
|
||||||
fr: RegionVid,
|
fr: RegionVid,
|
||||||
counter: &mut usize,
|
counter: &mut usize,
|
||||||
diag: &mut DiagnosticBuilder<'_>,
|
diag: &mut DiagnosticBuilder<'_>,
|
||||||
) -> Option<InternedString> {
|
) -> Option<InternedString> {
|
||||||
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
|
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
|
||||||
let argument_index = self.universal_regions
|
let argument_index = self
|
||||||
|
.universal_regions
|
||||||
.unnormalized_input_tys
|
.unnormalized_input_tys
|
||||||
.iter()
|
.iter()
|
||||||
.skip(implicit_inputs)
|
.skip(implicit_inputs)
|
||||||
.position(|arg_ty| {
|
.position(|arg_ty| {
|
||||||
debug!("give_name_if_anonymous_region_appears_in_arguments: arg_ty = {:?}", arg_ty);
|
debug!(
|
||||||
|
"give_name_if_anonymous_region_appears_in_arguments: arg_ty = {:?}",
|
||||||
|
arg_ty
|
||||||
|
);
|
||||||
tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
|
tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
|
||||||
})?
|
})?;
|
||||||
+ implicit_inputs;
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"give_name_if_anonymous_region_appears_in_arguments: \
|
"give_name_if_anonymous_region_appears_in_arguments: \
|
||||||
@ -150,9 +158,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
|
fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let arg_ty =
|
||||||
|
self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
|
||||||
|
if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
|
||||||
|
tcx,
|
||||||
|
mir_def_id,
|
||||||
|
fr,
|
||||||
|
arg_ty,
|
||||||
|
argument_index,
|
||||||
|
counter,
|
||||||
|
diag,
|
||||||
|
) {
|
||||||
|
return Some(region_name);
|
||||||
|
}
|
||||||
|
|
||||||
let region_name = self.synthesize_region_name(counter);
|
let region_name = self.synthesize_region_name(counter);
|
||||||
|
|
||||||
let argument_local = Local::new(argument_index + 1);
|
let argument_local = Local::new(argument_index + implicit_inputs + 1);
|
||||||
let argument_span = mir.local_decls[argument_local].source_info.span;
|
let argument_span = mir.local_decls[argument_local].source_info.span;
|
||||||
diag.span_label(
|
diag.span_label(
|
||||||
argument_span,
|
argument_span,
|
||||||
@ -162,6 +184,240 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
Some(region_name)
|
Some(region_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn give_name_if_we_can_match_hir_ty_from_argument(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||||
|
mir_def_id: DefId,
|
||||||
|
needle_fr: RegionVid,
|
||||||
|
argument_ty: Ty<'tcx>,
|
||||||
|
argument_index: usize,
|
||||||
|
counter: &mut usize,
|
||||||
|
diag: &mut DiagnosticBuilder<'_>,
|
||||||
|
) -> Option<InternedString> {
|
||||||
|
let mir_node_id = tcx.hir.as_local_node_id(mir_def_id)?;
|
||||||
|
let fn_decl = tcx.hir.fn_decl(mir_node_id)?;
|
||||||
|
let argument_hir_ty: &hir::Ty = &fn_decl.inputs[argument_index];
|
||||||
|
match argument_hir_ty.node {
|
||||||
|
// This indicates a variable with no type annotation, like
|
||||||
|
// `|x|`... in that case, we can't highlight the type but
|
||||||
|
// must highlight the variable.
|
||||||
|
hir::TyInfer => None,
|
||||||
|
|
||||||
|
_ => self.give_name_if_we_can_match_hir_ty(
|
||||||
|
tcx,
|
||||||
|
needle_fr,
|
||||||
|
argument_ty,
|
||||||
|
argument_hir_ty,
|
||||||
|
counter,
|
||||||
|
diag,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to highlight the specific part of a type annotation
|
||||||
|
/// that contains the anonymous reference we want to give a name
|
||||||
|
/// to. For example, we might produce an annotation like this:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
||||||
|
/// | - let's call the lifetime of this reference `'1`
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// the way this works is that we match up `argument_ty`, which is
|
||||||
|
/// a `Ty<'tcx>` (the internal form of the type) with
|
||||||
|
/// `argument_hir_ty`, a `hir::Ty` (the syntax of the type
|
||||||
|
/// annotation). We are descending through the types stepwise,
|
||||||
|
/// looking in to find the region `needle_fr` in the internal
|
||||||
|
/// type. Once we find that, we can use the span of the `hir::Ty`
|
||||||
|
/// to add the highlight.
|
||||||
|
///
|
||||||
|
/// This is a somewhat imperfect process, so long the way we also
|
||||||
|
/// keep track of the **closest** type we've found. If we fail to
|
||||||
|
/// find the exact `&` or `'_` to highlight, then we may fall back
|
||||||
|
/// to highlighting that closest type instead.
|
||||||
|
fn give_name_if_we_can_match_hir_ty(
|
||||||
|
&self,
|
||||||
|
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||||
|
needle_fr: RegionVid,
|
||||||
|
argument_ty: Ty<'tcx>,
|
||||||
|
argument_hir_ty: &hir::Ty,
|
||||||
|
counter: &mut usize,
|
||||||
|
diag: &mut DiagnosticBuilder<'_>,
|
||||||
|
) -> Option<InternedString> {
|
||||||
|
let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> = &mut Vec::new();
|
||||||
|
|
||||||
|
search_stack.push((argument_ty, argument_hir_ty));
|
||||||
|
|
||||||
|
let mut closest_match: &hir::Ty = argument_hir_ty;
|
||||||
|
|
||||||
|
while let Some((ty, hir_ty)) = search_stack.pop() {
|
||||||
|
// While we search, also track the closet match.
|
||||||
|
if tcx.any_free_region_meets(&ty, |r| r.to_region_vid() == needle_fr) {
|
||||||
|
closest_match = hir_ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
match (&ty.sty, &hir_ty.node) {
|
||||||
|
// Check if the `argument_ty` is `&'X ..` where `'X`
|
||||||
|
// is the region we are looking for -- if so, and we have a `&T`
|
||||||
|
// on the RHS, then we want to highlight the `&` like so:
|
||||||
|
//
|
||||||
|
// &
|
||||||
|
// - let's call the lifetime of this reference `'1`
|
||||||
|
(ty::TyRef(region, referent_ty, _), hir::TyRptr(_lifetime, referent_hir_ty)) => {
|
||||||
|
if region.to_region_vid() == needle_fr {
|
||||||
|
let region_name = self.synthesize_region_name(counter);
|
||||||
|
|
||||||
|
// Just grab the first character, the `&`.
|
||||||
|
let codemap = tcx.sess.codemap();
|
||||||
|
let ampersand_span = codemap.start_point(hir_ty.span);
|
||||||
|
|
||||||
|
diag.span_label(
|
||||||
|
ampersand_span,
|
||||||
|
format!(
|
||||||
|
"let's call the lifetime of this reference `{}`",
|
||||||
|
region_name
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Some(region_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, let's descend into the referent types.
|
||||||
|
search_stack.push((referent_ty, &referent_hir_ty.ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match up something like `Foo<'1>`
|
||||||
|
(ty::TyAdt(_adt_def, substs), hir::TyPath(hir::QPath::Resolved(None, path))) => {
|
||||||
|
if let Some(last_segment) = path.segments.last() {
|
||||||
|
if let Some(name) = self.match_adt_and_segment(
|
||||||
|
substs,
|
||||||
|
needle_fr,
|
||||||
|
last_segment,
|
||||||
|
counter,
|
||||||
|
diag,
|
||||||
|
search_stack,
|
||||||
|
) {
|
||||||
|
return Some(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following cases don't have lifetimes, so we
|
||||||
|
// just worry about trying to match up the rustc type
|
||||||
|
// with the HIR types:
|
||||||
|
(ty::TyTuple(elem_tys), hir::TyTup(elem_hir_tys)) => {
|
||||||
|
search_stack.extend(elem_tys.iter().cloned().zip(elem_hir_tys));
|
||||||
|
}
|
||||||
|
|
||||||
|
(ty::TySlice(elem_ty), hir::TySlice(elem_hir_ty))
|
||||||
|
| (ty::TyArray(elem_ty, _), hir::TyArray(elem_hir_ty, _)) => {
|
||||||
|
search_stack.push((elem_ty, elem_hir_ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
(ty::TyRawPtr(mut_ty), hir::TyPtr(mut_hir_ty)) => {
|
||||||
|
search_stack.push((mut_ty.ty, &mut_hir_ty.ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
// FIXME there are other cases that we could trace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let region_name = self.synthesize_region_name(counter);
|
||||||
|
diag.span_label(
|
||||||
|
closest_match.span,
|
||||||
|
format!("lifetime `{}` appears in this type", region_name),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Some(region_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We've found an enum/struct/union type with the substitutions
|
||||||
|
/// `substs` and -- in the HIR -- a path type with the final
|
||||||
|
/// segment `last_segment`. Try to find a `'_` to highlight in
|
||||||
|
/// the generic args (or, if not, to produce new zipped pairs of
|
||||||
|
/// types+hir to search through).
|
||||||
|
fn match_adt_and_segment<'hir>(
|
||||||
|
&self,
|
||||||
|
substs: &'tcx Substs<'tcx>,
|
||||||
|
needle_fr: RegionVid,
|
||||||
|
last_segment: &'hir hir::PathSegment,
|
||||||
|
counter: &mut usize,
|
||||||
|
diag: &mut DiagnosticBuilder<'_>,
|
||||||
|
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty)>,
|
||||||
|
) -> Option<InternedString> {
|
||||||
|
// Did the user give explicit arguments? (e.g., `Foo<..>`)
|
||||||
|
let args = last_segment.args.as_ref()?;
|
||||||
|
let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
|
||||||
|
match lifetime.name {
|
||||||
|
hir::LifetimeName::Param(_)
|
||||||
|
| hir::LifetimeName::Static
|
||||||
|
| hir::LifetimeName::Underscore => {
|
||||||
|
let region_name = self.synthesize_region_name(counter);
|
||||||
|
let ampersand_span = lifetime.span;
|
||||||
|
diag.span_label(ampersand_span, format!("let's call this `{}`", region_name));
|
||||||
|
return Some(region_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
hir::LifetimeName::Implicit => {
|
||||||
|
// In this case, the user left off the lifetime; so
|
||||||
|
// they wrote something like:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// x: Foo<T>
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// where the fully elaborated form is `Foo<'_, '1,
|
||||||
|
// T>`. We don't consider this a match; instead we let
|
||||||
|
// the "fully elaborated" type fallback above handle
|
||||||
|
// it.
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We've found an enum/struct/union type with the substitutions
|
||||||
|
/// `substs` and -- in the HIR -- a path with the generic
|
||||||
|
/// arguments `args`. If `needle_fr` appears in the args, return
|
||||||
|
/// the `hir::Lifetime` that corresponds to it. If not, push onto
|
||||||
|
/// `search_stack` the types+hir to search through.
|
||||||
|
fn try_match_adt_and_generic_args<'hir>(
|
||||||
|
&self,
|
||||||
|
substs: &'tcx Substs<'tcx>,
|
||||||
|
needle_fr: RegionVid,
|
||||||
|
args: &'hir hir::GenericArgs,
|
||||||
|
search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty)>,
|
||||||
|
) -> Option<&'hir hir::Lifetime> {
|
||||||
|
for (kind, hir_arg) in substs.iter().zip(&args.args) {
|
||||||
|
match (kind.unpack(), hir_arg) {
|
||||||
|
(UnpackedKind::Lifetime(r), hir::GenericArg::Lifetime(lt)) => {
|
||||||
|
if r.to_region_vid() == needle_fr {
|
||||||
|
return Some(lt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(UnpackedKind::Type(ty), hir::GenericArg::Type(hir_ty)) => {
|
||||||
|
search_stack.push((ty, hir_ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
(UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => {
|
||||||
|
// I *think* that HIR lowering should ensure this
|
||||||
|
// doesn't happen, even in erroneous
|
||||||
|
// programs. Else we should use delay-span-bug.
|
||||||
|
span_bug!(
|
||||||
|
hir_arg.span(),
|
||||||
|
"unmatched subst and hir arg: found {:?} vs {:?}",
|
||||||
|
kind,
|
||||||
|
hir_arg,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Find a closure upvar that contains `fr` and label it with a
|
/// Find a closure upvar that contains `fr` and label it with a
|
||||||
/// fully elaborated type, returning something like `'1`. Result
|
/// fully elaborated type, returning something like `'1`. Result
|
||||||
/// looks like:
|
/// looks like:
|
||||||
@ -178,7 +434,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
counter: &mut usize,
|
counter: &mut usize,
|
||||||
diag: &mut DiagnosticBuilder<'_>,
|
diag: &mut DiagnosticBuilder<'_>,
|
||||||
) -> Option<InternedString> {
|
) -> Option<InternedString> {
|
||||||
let upvar_index = self.universal_regions
|
let upvar_index = self
|
||||||
|
.universal_regions
|
||||||
.defining_ty
|
.defining_ty
|
||||||
.upvar_tys(tcx)
|
.upvar_tys(tcx)
|
||||||
.position(|upvar_ty| {
|
.position(|upvar_ty| {
|
||||||
@ -189,15 +446,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
tcx.any_free_region_meets(&upvar_ty, |r| r.to_region_vid() == fr)
|
tcx.any_free_region_meets(&upvar_ty, |r| r.to_region_vid() == fr)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let upvar_ty = self
|
||||||
|
.universal_regions
|
||||||
|
.defining_ty
|
||||||
|
.upvar_tys(tcx)
|
||||||
|
.nth(upvar_index);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"give_name_if_anonymous_region_appears_in_upvars: \
|
"give_name_if_anonymous_region_appears_in_upvars: \
|
||||||
found {:?} in upvar {} which has type {:?}",
|
found {:?} in upvar {} which has type {:?}",
|
||||||
fr,
|
fr, upvar_index, upvar_ty,
|
||||||
upvar_index,
|
|
||||||
self.universal_regions
|
|
||||||
.defining_ty
|
|
||||||
.upvar_tys(tcx)
|
|
||||||
.nth(upvar_index),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let region_name = self.synthesize_region_name(counter);
|
let region_name = self.synthesize_region_name(counter);
|
||||||
@ -229,9 +487,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||||||
counter: &mut usize,
|
counter: &mut usize,
|
||||||
diag: &mut DiagnosticBuilder<'_>,
|
diag: &mut DiagnosticBuilder<'_>,
|
||||||
) -> Option<InternedString> {
|
) -> Option<InternedString> {
|
||||||
let return_ty = self.universal_regions
|
let return_ty = self.universal_regions.unnormalized_output_ty;
|
||||||
.unnormalized_output_ty;
|
debug!(
|
||||||
debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty);
|
"give_name_if_anonymous_region_appears_in_output: return_ty = {:?}",
|
||||||
|
return_ty
|
||||||
|
);
|
||||||
if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
|
if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -689,6 +689,15 @@ impl CodeMap {
|
|||||||
self.span_until_char(sp, '{')
|
self.span_until_char(sp, '{')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a new span representing just the start-point of this span
|
||||||
|
pub fn start_point(&self, sp: Span) -> Span {
|
||||||
|
let pos = sp.lo().0;
|
||||||
|
let width = self.find_width_of_character_at_span(sp, false);
|
||||||
|
let corrected_start_position = pos.checked_add(width).unwrap_or(pos);
|
||||||
|
let end_point = BytePos(cmp::max(corrected_start_position, sp.lo().0));
|
||||||
|
sp.with_hi(end_point)
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a new span representing just the end-point of this span
|
/// Returns a new span representing just the end-point of this span
|
||||||
pub fn end_point(&self, sp: Span) -> Span {
|
pub fn end_point(&self, sp: Span) -> Span {
|
||||||
let pos = sp.hi().0;
|
let pos = sp.hi().0;
|
||||||
|
@ -11,7 +11,7 @@ LL | let mut lines_to_use: Vec<&CrateId> = Vec::new();
|
|||||||
| ---------------- lifetime `'2` appears in the type of `lines_to_use`
|
| ---------------- lifetime `'2` appears in the type of `lines_to_use`
|
||||||
LL | //~^ NOTE cannot infer an appropriate lifetime
|
LL | //~^ NOTE cannot infer an appropriate lifetime
|
||||||
LL | let push_id = |installed_id: &CrateId| {
|
LL | let push_id = |installed_id: &CrateId| {
|
||||||
| ------------ lifetime `'1` appears in this argument
|
| - let's call the lifetime of this reference `'1`
|
||||||
...
|
...
|
||||||
LL | lines_to_use.push(installed_id);
|
LL | lines_to_use.push(installed_id);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
|
||||||
|
@ -38,7 +38,7 @@ error: unsatisfied lifetime constraints
|
|||||||
LL | let mut f: Option<&u32> = None;
|
LL | let mut f: Option<&u32> = None;
|
||||||
| ----- lifetime `'2` appears in the type of `f`
|
| ----- lifetime `'2` appears in the type of `f`
|
||||||
LL | closure_expecting_bound(|x: &u32| {
|
LL | closure_expecting_bound(|x: &u32| {
|
||||||
| - lifetime `'1` appears in this argument
|
| - let's call the lifetime of this reference `'1`
|
||||||
LL | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
|
LL | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure
|
||||||
| ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ LL | let mut f: Option<&u32> = None;
|
|||||||
| ----- lifetime `'2` appears in the type of `f`
|
| ----- lifetime `'2` appears in the type of `f`
|
||||||
...
|
...
|
||||||
LL | closure_expecting_bound(|x: &'x u32| {
|
LL | closure_expecting_bound(|x: &'x u32| {
|
||||||
| - lifetime `'1` appears in this argument
|
| - let's call the lifetime of this reference `'1`
|
||||||
...
|
...
|
||||||
LL | f = Some(x);
|
LL | f = Some(x);
|
||||||
| ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
|
| ^^^^^^^^^^^ free region requires that `'1` must outlive `'2`
|
||||||
|
@ -14,7 +14,7 @@ error: unsatisfied lifetime constraints
|
|||||||
--> $DIR/static-return-lifetime-infered.rs:17:9
|
--> $DIR/static-return-lifetime-infered.rs:17:9
|
||||||
|
|
|
|
||||||
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
|
||||||
| ----- lifetime `'1` appears in this argument
|
| - let's call the lifetime of this reference `'1`
|
||||||
LL | self.x.iter().map(|a| a.0)
|
LL | self.x.iter().map(|a| a.0)
|
||||||
| ^^^^^^ cast requires that `'1` must outlive `'static`
|
| ^^^^^^ cast requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ error: unsatisfied lifetime constraints
|
|||||||
--> $DIR/dyn-trait-underscore.rs:18:5
|
--> $DIR/dyn-trait-underscore.rs:18:5
|
||||||
|
|
|
|
||||||
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
|
||||||
| ----- lifetime `'1` appears in this argument
|
| - let's call the lifetime of this reference `'1`
|
||||||
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
|
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
|
||||||
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
|
||||||
|
Loading…
Reference in New Issue
Block a user