mirror of https://github.com/rust-lang/rust.git
Account for HKTB when suggesting introduction of named lifetime
This commit is contained in:
parent
eda1a7adfc
commit
183dfac1f3
|
@ -2260,10 +2260,10 @@ impl TraitRef<'_> {
|
||||||
|
|
||||||
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
|
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
|
||||||
pub struct PolyTraitRef<'hir> {
|
pub struct PolyTraitRef<'hir> {
|
||||||
/// The `'a` in `<'a> Foo<&'a T>`.
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
||||||
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
pub bound_generic_params: &'hir [GenericParam<'hir>],
|
||||||
|
|
||||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
/// The `Foo<&'a T>` in `for <'a> Foo<&'a T>`.
|
||||||
pub trait_ref: TraitRef<'hir>,
|
pub trait_ref: TraitRef<'hir>,
|
||||||
|
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
|
@ -8,7 +8,6 @@ use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
||||||
use rustc_feature::BUILTIN_ATTRIBUTES;
|
use rustc_feature::BUILTIN_ATTRIBUTES;
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def::Namespace::{self, *};
|
use rustc_hir::def::Namespace::{self, *};
|
||||||
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
|
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind};
|
||||||
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
|
@ -20,6 +19,7 @@ use syntax::ast::{self, Ident, Path};
|
||||||
use syntax::util::lev_distance::find_best_match_for_name;
|
use syntax::util::lev_distance::find_best_match_for_name;
|
||||||
|
|
||||||
use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
|
use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
|
||||||
|
use crate::lifetimes::{HRLTSpanType, MissingLifetimeSpot};
|
||||||
use crate::path_names_to_string;
|
use crate::path_names_to_string;
|
||||||
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind};
|
use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind};
|
||||||
use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
|
use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
|
||||||
|
@ -1471,7 +1471,7 @@ crate fn add_missing_lifetime_specifiers_label(
|
||||||
count: usize,
|
count: usize,
|
||||||
lifetime_names: &FxHashSet<ast::Ident>,
|
lifetime_names: &FxHashSet<ast::Ident>,
|
||||||
snippet: Option<&str>,
|
snippet: Option<&str>,
|
||||||
missing_named_lifetime_spots: &[&hir::Generics<'_>],
|
missing_named_lifetime_spots: &[MissingLifetimeSpot<'_>],
|
||||||
) {
|
) {
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
err.span_label(span, format!("expected {} lifetime parameters", count));
|
err.span_label(span, format!("expected {} lifetime parameters", count));
|
||||||
|
@ -1484,21 +1484,41 @@ crate fn add_missing_lifetime_specifiers_label(
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg| {
|
let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| {
|
||||||
err.span_label(span, "expected named lifetime parameter");
|
err.span_label(span, "expected named lifetime parameter");
|
||||||
|
|
||||||
if let Some(generics) = missing_named_lifetime_spots.iter().last() {
|
for missing in missing_named_lifetime_spots.iter().rev() {
|
||||||
let mut introduce_suggestion = vec![];
|
let mut introduce_suggestion = vec![];
|
||||||
introduce_suggestion.push(match &generics.params {
|
let msg;
|
||||||
|
let should_break;
|
||||||
|
introduce_suggestion.push(match missing {
|
||||||
|
MissingLifetimeSpot::Generics(generics) => {
|
||||||
|
msg = "consider introducing a named lifetime parameter";
|
||||||
|
should_break = true;
|
||||||
|
match &generics.params {
|
||||||
[] => (generics.span, "<'lifetime>".to_string()),
|
[] => (generics.span, "<'lifetime>".to_string()),
|
||||||
[param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()),
|
[param, ..] => (param.span.shrink_to_lo(), "'lifetime, ".to_string()),
|
||||||
});
|
}
|
||||||
introduce_suggestion.push((span, sugg));
|
}
|
||||||
err.multipart_suggestion(
|
MissingLifetimeSpot::HRLT { span, span_type } => {
|
||||||
"consider introducing a named lifetime parameter",
|
msg = "consider introducing a Higher-Ranked lifetime";
|
||||||
introduce_suggestion,
|
should_break = false;
|
||||||
Applicability::MaybeIncorrect,
|
err.note(
|
||||||
|
"for more information on Higher-Ranked lifetimes, visit \
|
||||||
|
https://doc.rust-lang.org/nomicon/hrtb.html",
|
||||||
);
|
);
|
||||||
|
let suggestion = match span_type {
|
||||||
|
HRLTSpanType::Empty => "for<'lifetime> ",
|
||||||
|
HRLTSpanType::Tail => ", 'lifetime",
|
||||||
|
};
|
||||||
|
(*span, suggestion.to_string())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
introduce_suggestion.push((span, sugg.to_string()));
|
||||||
|
err.multipart_suggestion(msg, introduce_suggestion, Applicability::MaybeIncorrect);
|
||||||
|
if should_break {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1513,13 +1533,13 @@ crate fn add_missing_lifetime_specifiers_label(
|
||||||
suggest_existing(err, format!("{}<{}>", snippet, name));
|
suggest_existing(err, format!("{}<{}>", snippet, name));
|
||||||
}
|
}
|
||||||
(0, _, Some("&")) => {
|
(0, _, Some("&")) => {
|
||||||
suggest_new(err, "&'lifetime ".to_string());
|
suggest_new(err, "&'lifetime ");
|
||||||
}
|
}
|
||||||
(0, _, Some("'_")) => {
|
(0, _, Some("'_")) => {
|
||||||
suggest_new(err, "'lifetime".to_string());
|
suggest_new(err, "'lifetime");
|
||||||
}
|
}
|
||||||
(0, _, Some(snippet)) if !snippet.ends_with(">") => {
|
(0, _, Some(snippet)) if !snippet.ends_with(">") => {
|
||||||
suggest_new(err, format!("{}<'lifetime>", snippet));
|
suggest_new(err, &format!("{}<'lifetime>", snippet));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
err.span_label(span, "expected lifetime parameter");
|
err.span_label(span, "expected lifetime parameter");
|
||||||
|
|
|
@ -153,6 +153,22 @@ struct NamedRegionMap {
|
||||||
object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
|
object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate enum MissingLifetimeSpot<'tcx> {
|
||||||
|
Generics(&'tcx hir::Generics<'tcx>),
|
||||||
|
HRLT { span: Span, span_type: HRLTSpanType },
|
||||||
|
}
|
||||||
|
|
||||||
|
crate enum HRLTSpanType {
|
||||||
|
Empty,
|
||||||
|
Tail,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Into<MissingLifetimeSpot<'tcx>> for &'tcx hir::Generics<'tcx> {
|
||||||
|
fn into(self) -> MissingLifetimeSpot<'tcx> {
|
||||||
|
MissingLifetimeSpot::Generics(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct LifetimeContext<'a, 'tcx> {
|
struct LifetimeContext<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
map: &'a mut NamedRegionMap,
|
map: &'a mut NamedRegionMap,
|
||||||
|
@ -186,7 +202,7 @@ struct LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
/// When encountering an undefined named lifetime, we will suggest introducing it in these
|
/// When encountering an undefined named lifetime, we will suggest introducing it in these
|
||||||
/// places.
|
/// places.
|
||||||
missing_named_lifetime_spots: Vec<&'tcx hir::Generics<'tcx>>,
|
missing_named_lifetime_spots: Vec<MissingLifetimeSpot<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -389,7 +405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ItemKind::Fn(ref sig, ref generics, _) => {
|
hir::ItemKind::Fn(ref sig, ref generics, _) => {
|
||||||
self.missing_named_lifetime_spots.push(generics);
|
self.missing_named_lifetime_spots.push(generics.into());
|
||||||
self.visit_early_late(None, &sig.decl, generics, |this| {
|
self.visit_early_late(None, &sig.decl, generics, |this| {
|
||||||
intravisit::walk_item(this, item);
|
intravisit::walk_item(this, item);
|
||||||
});
|
});
|
||||||
|
@ -424,7 +440,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
| hir::ItemKind::Trait(_, _, ref generics, ..)
|
| hir::ItemKind::Trait(_, _, ref generics, ..)
|
||||||
| hir::ItemKind::TraitAlias(ref generics, ..)
|
| hir::ItemKind::TraitAlias(ref generics, ..)
|
||||||
| hir::ItemKind::Impl { ref generics, .. } => {
|
| hir::ItemKind::Impl { ref generics, .. } => {
|
||||||
self.missing_named_lifetime_spots.push(generics);
|
self.missing_named_lifetime_spots.push(generics.into());
|
||||||
|
|
||||||
// Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
|
// Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
|
||||||
// This is not true for other kinds of items.x
|
// This is not true for other kinds of items.x
|
||||||
|
@ -696,7 +712,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
|
||||||
use self::hir::TraitItemKind::*;
|
use self::hir::TraitItemKind::*;
|
||||||
self.missing_named_lifetime_spots.push(&trait_item.generics);
|
self.missing_named_lifetime_spots.push((&trait_item.generics).into());
|
||||||
match trait_item.kind {
|
match trait_item.kind {
|
||||||
Method(ref sig, _) => {
|
Method(ref sig, _) => {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
@ -753,7 +769,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
|
||||||
use self::hir::ImplItemKind::*;
|
use self::hir::ImplItemKind::*;
|
||||||
self.missing_named_lifetime_spots.push(&impl_item.generics);
|
self.missing_named_lifetime_spots.push((&impl_item.generics).into());
|
||||||
match impl_item.kind {
|
match impl_item.kind {
|
||||||
Method(ref sig, _) => {
|
Method(ref sig, _) => {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
@ -953,6 +969,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
) {
|
) {
|
||||||
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
|
debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref);
|
||||||
|
|
||||||
|
let should_pop_missing_lt = self.is_trait_ref_fn_scope(trait_ref);
|
||||||
if !self.trait_ref_hack
|
if !self.trait_ref_hack
|
||||||
|| trait_ref.bound_generic_params.iter().any(|param| match param.kind {
|
|| trait_ref.bound_generic_params.iter().any(|param| match param.kind {
|
||||||
GenericParamKind::Lifetime { .. } => true,
|
GenericParamKind::Lifetime { .. } => true,
|
||||||
|
@ -988,10 +1005,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |old_scope, this| {
|
||||||
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
|
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
|
||||||
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
||||||
this.visit_trait_ref(&trait_ref.trait_ref)
|
this.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.visit_trait_ref(&trait_ref.trait_ref)
|
self.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
|
}
|
||||||
|
if should_pop_missing_lt {
|
||||||
|
self.missing_named_lifetime_spots.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1832,11 +1852,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
lifetime_ref
|
lifetime_ref
|
||||||
);
|
);
|
||||||
err.span_label(lifetime_ref.span, "undeclared lifetime");
|
err.span_label(lifetime_ref.span, "undeclared lifetime");
|
||||||
if !self.is_in_fn_syntax {
|
for missing in &self.missing_named_lifetime_spots {
|
||||||
for generics in &self.missing_named_lifetime_spots {
|
match missing {
|
||||||
|
MissingLifetimeSpot::Generics(generics) => {
|
||||||
let (span, sugg) = match &generics.params {
|
let (span, sugg) = match &generics.params {
|
||||||
[] => (generics.span, format!("<{}>", lifetime_ref)),
|
[] => (generics.span, format!("<{}>", lifetime_ref)),
|
||||||
[param, ..] => (param.span.shrink_to_lo(), format!("{}, ", lifetime_ref)),
|
[param, ..] => {
|
||||||
|
(param.span.shrink_to_lo(), format!("{}, ", lifetime_ref))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
|
@ -1845,6 +1868,26 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
MissingLifetimeSpot::HRLT { span, span_type } => {
|
||||||
|
err.span_suggestion(
|
||||||
|
*span,
|
||||||
|
&format!(
|
||||||
|
"consider introducing a Higher-Ranked lifetime `{}` here",
|
||||||
|
lifetime_ref
|
||||||
|
),
|
||||||
|
match span_type {
|
||||||
|
HRLTSpanType::Empty => format!("for<{}> ", lifetime_ref),
|
||||||
|
HRLTSpanType::Tail => format!(", {}", lifetime_ref),
|
||||||
|
}
|
||||||
|
.to_string(),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
err.note(
|
||||||
|
"for more information on Higher-Ranked lifetimes, visit \
|
||||||
|
https://doc.rust-lang.org/nomicon/hrtb.html",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
|
@ -2441,6 +2484,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
let elided_len = elided_params.len();
|
let elided_len = elided_params.len();
|
||||||
|
|
||||||
|
// FIXME: collect spans of the input params when appropriate to use in the diagnostic.
|
||||||
for (i, info) in elided_params.into_iter().enumerate() {
|
for (i, info) in elided_params.into_iter().enumerate() {
|
||||||
let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions } = info;
|
let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions } = info;
|
||||||
|
|
||||||
|
@ -2747,6 +2791,27 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
let old_value = self.map.defs.remove(&lifetime_ref.hir_id);
|
let old_value = self.map.defs.remove(&lifetime_ref.hir_id);
|
||||||
assert_eq!(old_value, Some(bad_def));
|
assert_eq!(old_value, Some(bad_def));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_trait_ref_fn_scope(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) -> bool {
|
||||||
|
if let Res::Def(_, did) = trait_ref.trait_ref.path.res {
|
||||||
|
if [
|
||||||
|
self.tcx.lang_items().fn_once_trait(),
|
||||||
|
self.tcx.lang_items().fn_trait(),
|
||||||
|
self.tcx.lang_items().fn_mut_trait(),
|
||||||
|
]
|
||||||
|
.contains(&Some(did))
|
||||||
|
{
|
||||||
|
let (span, span_type) = match &trait_ref.bound_generic_params {
|
||||||
|
[] => (trait_ref.span.shrink_to_lo(), HRLTSpanType::Empty),
|
||||||
|
[.., bound] => (bound.span.shrink_to_hi(), HRLTSpanType::Tail),
|
||||||
|
};
|
||||||
|
self.missing_named_lifetime_spots
|
||||||
|
.push(MissingLifetimeSpot::HRLT { span, span_type });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detects late-bound lifetimes and inserts them into
|
/// Detects late-bound lifetimes and inserts them into
|
||||||
|
|
|
@ -1307,6 +1307,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||||
|
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||||
|
// ---- ---- ^^^^^^^
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
binding.span,
|
binding.span,
|
||||||
|
|
|
@ -9,6 +9,8 @@ LL | let y: &'test u32 = x;
|
||||||
error[E0261]: use of undeclared lifetime name `'test`
|
error[E0261]: use of undeclared lifetime name `'test`
|
||||||
--> $DIR/no_introducing_in_band_in_locals.rs:10:16
|
--> $DIR/no_introducing_in_band_in_locals.rs:10:16
|
||||||
|
|
|
|
||||||
|
LL | fn bar() {
|
||||||
|
| - help: consider introducing lifetime `'test` here: `<'test>`
|
||||||
LL | let y: fn(&'test u32) = foo2;
|
LL | let y: fn(&'test u32) = foo2;
|
||||||
| ^^^^^ undeclared lifetime
|
| ^^^^^ undeclared lifetime
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,11 @@ LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {}
|
||||||
| ^ expected named lifetime parameter
|
| ^ expected named lifetime parameter
|
||||||
|
|
|
|
||||||
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2
|
||||||
|
= note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||||
|
help: consider introducing a Higher-Ranked lifetime
|
||||||
|
|
|
||||||
|
LL | fn bar<F: for<'lifetime> Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
|
||||||
|
| ^^^^^^^^^^^^^^ ^^^^^^^^^^
|
||||||
help: consider introducing a named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
||||||
|
|
|
|
||||||
LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
|
LL | fn bar<'lifetime, F: Fn(&u8, &u8) -> &'lifetime u8>(f: &F) {}
|
||||||
|
|
|
@ -88,12 +88,32 @@ error[E0261]: use of undeclared lifetime name `'b`
|
||||||
|
|
|
|
||||||
LL | ... &'b isize,
|
LL | ... &'b isize,
|
||||||
| ^^ undeclared lifetime
|
| ^^ undeclared lifetime
|
||||||
|
|
|
||||||
|
= note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||||
|
help: consider introducing lifetime `'b` here
|
||||||
|
|
|
||||||
|
LL | fn fn_types<'b>(a: &'a isize,
|
||||||
|
| ^^^^
|
||||||
|
help: consider introducing a Higher-Ranked lifetime `'b` here
|
||||||
|
|
|
||||||
|
LL | b: Box<dyn for<'a, 'b> FnOnce(&'a isize,
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error[E0261]: use of undeclared lifetime name `'b`
|
error[E0261]: use of undeclared lifetime name `'b`
|
||||||
--> $DIR/regions-name-undeclared.rs:45:36
|
--> $DIR/regions-name-undeclared.rs:45:36
|
||||||
|
|
|
|
||||||
LL | ... &'b isize)>,
|
LL | ... &'b isize)>,
|
||||||
| ^^ undeclared lifetime
|
| ^^ undeclared lifetime
|
||||||
|
|
|
||||||
|
= note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||||
|
help: consider introducing lifetime `'b` here
|
||||||
|
|
|
||||||
|
LL | fn fn_types<'b>(a: &'a isize,
|
||||||
|
| ^^^^
|
||||||
|
help: consider introducing a Higher-Ranked lifetime `'b` here
|
||||||
|
|
|
||||||
|
LL | b: Box<dyn for<'a, 'b> FnOnce(&'a isize,
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error[E0261]: use of undeclared lifetime name `'a`
|
error[E0261]: use of undeclared lifetime name `'a`
|
||||||
--> $DIR/regions-name-undeclared.rs:46:17
|
--> $DIR/regions-name-undeclared.rs:46:17
|
||||||
|
|
Loading…
Reference in New Issue