Auto merge of #82743 - jackh726:resolve-refactor, r=nikomatsakis
Refactor rustc_resolve::late::lifetimes to resolve per-item There are some changes to tests that I'd like some feedback on; so this is still WIP. The reason behind this change will (hopefully) allow us to (as part of #76814) be able to essentially use the lifetime resolve code to resolve *all* late bound vars (including those of super traits). Currently, it only resolves those that are *syntactically* in scope. In #76814, I'm essentially finding that I would essentially have to redo the passing of bound vars through scopes (i.e. when instantiating a poly trait ref), and that's what this code does anyways. However, to be able to do this (ask super traits what bound vars are in scope), we have to be able to resolve items separately. The first commit is actually partially orthogonal. Essentially removing one use of late bound debruijn indices. Not exactly sure who would be best to review here. Let r? `@nikomatsakis`
This commit is contained in:
commit
52e3dffa50
22 changed files with 580 additions and 609 deletions
|
@ -78,9 +78,4 @@ pub struct ResolveLifetimes {
|
|||
/// be late-bound if (a) it does NOT appear in a where-clause and
|
||||
/// (b) it DOES appear in the arguments.
|
||||
pub late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
|
||||
|
||||
/// For each type and trait definition, maps type parameters
|
||||
/// to the trait object lifetime defaults computed from them.
|
||||
pub object_lifetime_defaults:
|
||||
FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
|
||||
}
|
||||
|
|
|
@ -1258,8 +1258,19 @@ rustc_queries! {
|
|||
desc { "looking up link arguments for a crate" }
|
||||
}
|
||||
|
||||
/// Lifetime resolution. See `middle::resolve_lifetimes`.
|
||||
query resolve_lifetimes(_: CrateNum) -> ResolveLifetimes {
|
||||
/// Does lifetime resolution, but does not descend into trait items. This
|
||||
/// should only be used for resolving lifetimes of on trait definitions,
|
||||
/// and is used to avoid cycles. Importantly, `resolve_lifetimes` still visits
|
||||
/// the same lifetimes and is responsible for diagnostics.
|
||||
/// See `rustc_resolve::late::lifetimes for details.
|
||||
query resolve_lifetimes_trait_definition(_: LocalDefId) -> ResolveLifetimes {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
desc { "resolving lifetimes for a trait definition" }
|
||||
}
|
||||
/// Does lifetime resolution on items. Importantly, we can't resolve
|
||||
/// lifetimes directly on things like trait methods, because of trait params.
|
||||
/// See `rustc_resolve::late::lifetimes for details.
|
||||
query resolve_lifetimes(_: LocalDefId) -> ResolveLifetimes {
|
||||
storage(ArenaCacheSelector<'tcx>)
|
||||
desc { "resolving lifetimes" }
|
||||
}
|
||||
|
@ -1271,9 +1282,13 @@ rustc_queries! {
|
|||
Option<(LocalDefId, &'tcx FxHashSet<ItemLocalId>)> {
|
||||
desc { "testing if a region is late bound" }
|
||||
}
|
||||
/// For a given item (like a struct), gets the default lifetimes to be used
|
||||
/// for each paramter if a trait object were to be passed for that parameter.
|
||||
/// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
|
||||
/// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
|
||||
query object_lifetime_defaults_map(_: LocalDefId)
|
||||
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
|
||||
desc { "looking up lifetime defaults for a region" }
|
||||
-> Option<Vec<ObjectLifetimeDefault>> {
|
||||
desc { "looking up lifetime defaults for a region on an item" }
|
||||
}
|
||||
|
||||
query visibility(def_id: DefId) -> ty::Visibility {
|
||||
|
|
|
@ -2641,6 +2641,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
|
||||
debug!(?id, "named_region");
|
||||
self.named_region_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
|
||||
}
|
||||
|
||||
|
@ -2649,9 +2650,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
.map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id))
|
||||
}
|
||||
|
||||
pub fn object_lifetime_defaults(self, id: HirId) -> Option<&'tcx [ObjectLifetimeDefault]> {
|
||||
pub fn object_lifetime_defaults(self, id: HirId) -> Option<Vec<ObjectLifetimeDefault>> {
|
||||
self.object_lifetime_defaults_map(id.owner)
|
||||
.and_then(|map| map.get(&id.local_id).map(|v| &**v))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// ignore-tidy-filelength
|
||||
//! Name resolution for lifetimes.
|
||||
//!
|
||||
//! Name resolution for lifetimes follows *much* simpler rules than the
|
||||
|
@ -11,7 +12,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefIdMap, LOCAL_CRATE};
|
||||
use rustc_hir::def_id::DefIdMap;
|
||||
use rustc_hir::hir_id::ItemLocalId;
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName, QPath};
|
||||
|
@ -26,6 +27,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
|||
use rustc_span::Span;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::mem::take;
|
||||
|
||||
use tracing::debug;
|
||||
|
@ -135,7 +137,7 @@ impl RegionExt for Region {
|
|||
/// FIXME. This struct gets converted to a `ResolveLifetimes` for
|
||||
/// actual use. It has the same data, but indexed by `LocalDefId`. This
|
||||
/// is silly.
|
||||
#[derive(Default)]
|
||||
#[derive(Debug, Default)]
|
||||
struct NamedRegionMap {
|
||||
// maps from every use of a named (not anonymous) lifetime to a
|
||||
// `Region` describing how that region is bound
|
||||
|
@ -145,10 +147,6 @@ struct NamedRegionMap {
|
|||
// be late-bound if (a) it does NOT appear in a where-clause and
|
||||
// (b) it DOES appear in the arguments.
|
||||
late_bound: HirIdSet,
|
||||
|
||||
// For each type and trait definition, maps type parameters
|
||||
// to the trait object lifetime defaults computed from them.
|
||||
object_lifetime_defaults: HirIdMap<Vec<ObjectLifetimeDefault>>,
|
||||
}
|
||||
|
||||
crate struct LifetimeContext<'a, 'tcx> {
|
||||
|
@ -176,6 +174,11 @@ crate struct LifetimeContext<'a, 'tcx> {
|
|||
|
||||
is_in_const_generic: bool,
|
||||
|
||||
/// Indicates that we only care about the definition of a trait. This should
|
||||
/// be false if the `Item` we are resolving lifetimes for is not a trait or
|
||||
/// we eventually need lifetimes resolve for trait items.
|
||||
trait_definition_only: bool,
|
||||
|
||||
/// List of labels in the function/method currently under analysis.
|
||||
labels_in_fn: Vec<Ident>,
|
||||
|
||||
|
@ -252,6 +255,42 @@ enum Scope<'a> {
|
|||
Root,
|
||||
}
|
||||
|
||||
// A helper struct for debugging scopes without printing parent scopes
|
||||
struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
|
||||
|
||||
impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.0 {
|
||||
Scope::Binder {
|
||||
lifetimes,
|
||||
next_early_index,
|
||||
track_lifetime_uses,
|
||||
opaque_type_parent,
|
||||
s: _,
|
||||
} => f
|
||||
.debug_struct("Binder")
|
||||
.field("lifetimes", lifetimes)
|
||||
.field("next_early_index", next_early_index)
|
||||
.field("track_lifetime_uses", track_lifetime_uses)
|
||||
.field("opaque_type_parent", opaque_type_parent)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::Body { id, s: _ } => {
|
||||
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
|
||||
}
|
||||
Scope::Elision { elide, s: _ } => {
|
||||
f.debug_struct("Elision").field("elide", elide).field("s", &"..").finish()
|
||||
}
|
||||
Scope::ObjectLifetimeDefault { lifetime, s: _ } => f
|
||||
.debug_struct("ObjectLifetimeDefault")
|
||||
.field("lifetime", lifetime)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::Root => f.debug_struct("Root").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Elide {
|
||||
/// Use a fresh anonymous late-bound lifetime each time, by
|
||||
|
@ -283,26 +322,91 @@ const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
|
|||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers {
|
||||
resolve_lifetimes_trait_definition,
|
||||
resolve_lifetimes,
|
||||
|
||||
named_region_map: |tcx, id| tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id),
|
||||
named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
|
||||
is_late_bound_map,
|
||||
object_lifetime_defaults_map: |tcx, id| {
|
||||
tcx.resolve_lifetimes(LOCAL_CRATE).object_lifetime_defaults.get(&id)
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(id);
|
||||
match tcx.hir().find(hir_id) {
|
||||
Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item),
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
||||
/// Computes the `ResolveLifetimes` map that contains data for the
|
||||
/// entire crate. You should not read the result of this query
|
||||
/// directly, but rather use `named_region_map`, `is_late_bound_map`,
|
||||
/// etc.
|
||||
fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> ResolveLifetimes {
|
||||
assert_eq!(for_krate, LOCAL_CRATE);
|
||||
/// Like `resolve_lifetimes`, but does not resolve lifetimes for trait items.
|
||||
/// Also does not generate any diagnostics.
|
||||
///
|
||||
/// This is ultimately a subset of the `resolve_lifetimes` work. It effectively
|
||||
/// resolves lifetimes only within the trait "header" -- that is, the trait
|
||||
/// and supertrait list. In contrast, `resolve_lifetimes` resolves all the
|
||||
/// lifetimes within the trait and its items. There is room to refactor this,
|
||||
/// for example to resolve lifetimes for each trait item in separate queries,
|
||||
/// but it's convenient to do the entire trait at once because the lifetimes
|
||||
/// from the trait definition are in scope within the trait items as well.
|
||||
///
|
||||
/// The reason for this separate call is to resolve what would otherwise
|
||||
/// be a cycle. Consider this example:
|
||||
///
|
||||
/// ```rust
|
||||
/// trait Base<'a> {
|
||||
/// type BaseItem;
|
||||
/// }
|
||||
/// trait Sub<'b>: for<'a> Base<'a> {
|
||||
/// type SubItem: Sub<BaseItem = &'b u32>;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When we resolve `Sub` and all its items, we also have to resolve `Sub<BaseItem = &'b u32>`.
|
||||
/// To figure out the index of `'b`, we have to know about the supertraits
|
||||
/// of `Sub` so that we can determine that the `for<'a>` will be in scope.
|
||||
/// (This is because we -- currently at least -- flatten all the late-bound
|
||||
/// lifetimes into a single binder.) This requires us to resolve the
|
||||
/// *trait definition* of `Sub`; basically just enough lifetime information
|
||||
/// to look at the supertraits.
|
||||
#[tracing::instrument(level = "debug", skip(tcx))]
|
||||
fn resolve_lifetimes_trait_definition(
|
||||
tcx: TyCtxt<'_>,
|
||||
local_def_id: LocalDefId,
|
||||
) -> ResolveLifetimes {
|
||||
do_resolve(tcx, local_def_id, true)
|
||||
}
|
||||
|
||||
let named_region_map = krate(tcx);
|
||||
/// Computes the `ResolveLifetimes` map that contains data for an entire `Item`.
|
||||
/// You should not read the result of this query directly, but rather use
|
||||
/// `named_region_map`, `is_late_bound_map`, etc.
|
||||
#[tracing::instrument(level = "debug", skip(tcx))]
|
||||
fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes {
|
||||
do_resolve(tcx, local_def_id, false)
|
||||
}
|
||||
|
||||
fn do_resolve(
|
||||
tcx: TyCtxt<'_>,
|
||||
local_def_id: LocalDefId,
|
||||
trait_definition_only: bool,
|
||||
) -> ResolveLifetimes {
|
||||
let item = tcx.hir().expect_item(tcx.hir().local_def_id_to_hir_id(local_def_id));
|
||||
let mut named_region_map =
|
||||
NamedRegionMap { defs: Default::default(), late_bound: Default::default() };
|
||||
let mut visitor = LifetimeContext {
|
||||
tcx,
|
||||
map: &mut named_region_map,
|
||||
scope: ROOT_SCOPE,
|
||||
trait_ref_hack: false,
|
||||
is_in_fn_syntax: false,
|
||||
is_in_const_generic: false,
|
||||
trait_definition_only,
|
||||
labels_in_fn: vec![],
|
||||
xcrate_object_lifetime_defaults: Default::default(),
|
||||
lifetime_uses: &mut Default::default(),
|
||||
missing_named_lifetime_spots: vec![],
|
||||
};
|
||||
visitor.visit_item(item);
|
||||
|
||||
let mut rl = ResolveLifetimes::default();
|
||||
|
||||
|
@ -314,14 +418,58 @@ fn resolve_lifetimes(tcx: TyCtxt<'_>, for_krate: CrateNum) -> ResolveLifetimes {
|
|||
let map = rl.late_bound.entry(hir_id.owner).or_default();
|
||||
map.insert(hir_id.local_id);
|
||||
}
|
||||
for (hir_id, v) in named_region_map.object_lifetime_defaults {
|
||||
let map = rl.object_lifetime_defaults.entry(hir_id.owner).or_default();
|
||||
map.insert(hir_id.local_id, v);
|
||||
}
|
||||
|
||||
debug!(?rl.defs);
|
||||
rl
|
||||
}
|
||||
|
||||
/// Given `any` owner (structs, traits, trait methods, etc.), does lifetime resolution.
|
||||
/// There are two important things this does.
|
||||
/// First, we have to resolve lifetimes for
|
||||
/// the entire *`Item`* that contains this owner, because that's the largest "scope"
|
||||
/// where we can have relevant lifetimes.
|
||||
/// Second, if we are asking for lifetimes in a trait *definition*, we use `resolve_lifetimes_trait_definition`
|
||||
/// instead of `resolve_lifetimes`, which does not descend into the trait items and does not emit diagnostics.
|
||||
/// This allows us to avoid cycles. Importantly, if we ask for lifetimes for lifetimes that have an owner
|
||||
/// other than the trait itself (like the trait methods or associated types), then we just use the regular
|
||||
/// `resolve_lifetimes`.
|
||||
fn resolve_lifetimes_for<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx ResolveLifetimes {
|
||||
let item_id = item_for(tcx, def_id);
|
||||
if item_id == def_id {
|
||||
let item = tcx.hir().item(hir::ItemId { def_id: item_id });
|
||||
match item.kind {
|
||||
hir::ItemKind::Trait(..) => tcx.resolve_lifetimes_trait_definition(item_id),
|
||||
_ => tcx.resolve_lifetimes(item_id),
|
||||
}
|
||||
} else {
|
||||
tcx.resolve_lifetimes(item_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds the `Item` that contains the given `LocalDefId`
|
||||
fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(local_def_id);
|
||||
match tcx.hir().find(hir_id) {
|
||||
Some(Node::Item(item)) => {
|
||||
return item.def_id;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let item = {
|
||||
let hir = tcx.hir();
|
||||
let mut parent_iter = hir.parent_iter(hir_id);
|
||||
loop {
|
||||
let node = parent_iter.next().map(|n| n.1);
|
||||
match node {
|
||||
Some(hir::Node::Item(item)) => break item.def_id,
|
||||
Some(hir::Node::Crate(_)) | None => bug!("Called `item_for` on an Item."),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
};
|
||||
item
|
||||
}
|
||||
|
||||
fn is_late_bound_map<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
|
@ -344,37 +492,10 @@ fn is_late_bound_map<'tcx>(
|
|||
|
||||
tcx.is_late_bound_map(def_id.expect_local())
|
||||
}
|
||||
_ => tcx.resolve_lifetimes(LOCAL_CRATE).late_bound.get(&def_id).map(|lt| (def_id, lt)),
|
||||
_ => resolve_lifetimes_for(tcx, def_id).late_bound.get(&def_id).map(|lt| (def_id, lt)),
|
||||
}
|
||||
}
|
||||
|
||||
fn krate(tcx: TyCtxt<'_>) -> NamedRegionMap {
|
||||
let krate = tcx.hir().krate();
|
||||
let mut map = NamedRegionMap {
|
||||
defs: Default::default(),
|
||||
late_bound: Default::default(),
|
||||
object_lifetime_defaults: compute_object_lifetime_defaults(tcx),
|
||||
};
|
||||
{
|
||||
let mut visitor = LifetimeContext {
|
||||
tcx,
|
||||
map: &mut map,
|
||||
scope: ROOT_SCOPE,
|
||||
trait_ref_hack: false,
|
||||
is_in_fn_syntax: false,
|
||||
is_in_const_generic: false,
|
||||
labels_in_fn: vec![],
|
||||
xcrate_object_lifetime_defaults: Default::default(),
|
||||
lifetime_uses: &mut Default::default(),
|
||||
missing_named_lifetime_spots: vec![],
|
||||
};
|
||||
for item in krate.items.values() {
|
||||
visitor.visit_item(item);
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
|
||||
/// In traits, there is an implicit `Self` type parameter which comes before the generics.
|
||||
/// We have to account for this when computing the index of the other generic parameters.
|
||||
/// This function returns whether there is such an implicit parameter defined on the given item.
|
||||
|
@ -392,6 +513,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
// We want to nest trait/impl items in their parent, but nothing else.
|
||||
fn visit_nested_item(&mut self, _: hir::ItemId) {}
|
||||
|
||||
fn visit_trait_item_ref(&mut self, ii: &'tcx hir::TraitItemRef) {
|
||||
if !self.trait_definition_only {
|
||||
intravisit::walk_trait_item_ref(self, ii)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_nested_body(&mut self, body: hir::BodyId) {
|
||||
// Each body has their own set of labels, save labels.
|
||||
let saved = take(&mut self.labels_in_fn);
|
||||
|
@ -430,6 +557,37 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
// Opaque types are visited when we visit the
|
||||
// `TyKind::OpaqueDef`, so that they have the lifetimes from
|
||||
// their parent opaque_ty in scope.
|
||||
//
|
||||
// The core idea here is that since OpaqueTys are generated with the impl Trait as
|
||||
// their owner, we can keep going until we find the Item that owns that. We then
|
||||
// conservatively add all resolved lifetimes. Otherwise we run into problems in
|
||||
// cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
|
||||
for (_hir_id, node) in
|
||||
self.tcx.hir().parent_iter(self.tcx.hir().local_def_id_to_hir_id(item.def_id))
|
||||
{
|
||||
match node {
|
||||
hir::Node::Item(parent_item) => {
|
||||
let resolved_lifetimes: &ResolveLifetimes =
|
||||
self.tcx.resolve_lifetimes(item_for(self.tcx, parent_item.def_id));
|
||||
// We need to add *all* deps, since opaque tys may want them from *us*
|
||||
for (&owner, defs) in resolved_lifetimes.defs.iter() {
|
||||
defs.iter().for_each(|(&local_id, region)| {
|
||||
self.map
|
||||
.defs
|
||||
.insert(hir::HirId { owner, local_id }, region.clone());
|
||||
});
|
||||
}
|
||||
for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() {
|
||||
late_bound.iter().for_each(|&local_id| {
|
||||
self.map.late_bound.insert(hir::HirId { owner, local_id });
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
hir::Node::Crate(_) => bug!("No Item about an OpaqueTy"),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemKind::TyAlias(_, ref generics)
|
||||
| hir::ItemKind::Enum(_, ref generics)
|
||||
|
@ -495,9 +653,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||
debug!("visit_ty: id={:?} ty={:?}", ty.hir_id, ty);
|
||||
debug!("visit_ty: ty.kind={:?}", ty.kind);
|
||||
match ty.kind {
|
||||
hir::TyKind::BareFn(ref c) => {
|
||||
let next_early_index = self.next_early_index();
|
||||
|
@ -541,7 +698,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
self.is_in_fn_syntax = was_in_fn_syntax;
|
||||
}
|
||||
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
|
||||
debug!("visit_ty: TraitObject(bounds={:?}, lifetime={:?})", bounds, lifetime);
|
||||
debug!(?bounds, ?lifetime, "TraitObject");
|
||||
for bound in bounds {
|
||||
self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
|
||||
}
|
||||
|
@ -652,14 +809,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
};
|
||||
|
||||
if !parent_is_item {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
lifetime.span,
|
||||
E0657,
|
||||
"`impl Trait` can only capture lifetimes \
|
||||
bound at the fn or impl level"
|
||||
)
|
||||
.emit();
|
||||
if !self.trait_definition_only {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
lifetime.span,
|
||||
E0657,
|
||||
"`impl Trait` can only capture lifetimes \
|
||||
bound at the fn or impl level"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
self.uninsert_lifetime_on_error(lifetime, def.unwrap());
|
||||
}
|
||||
}
|
||||
|
@ -670,7 +829,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
// We want to start our early-bound indices at the end of the parent scope,
|
||||
// not including any parent `impl Trait`s.
|
||||
let mut index = self.next_early_index_for_opaque_type();
|
||||
debug!("visit_ty: index = {}", index);
|
||||
debug!(?index);
|
||||
|
||||
let mut elision = None;
|
||||
let mut lifetimes = FxHashMap::default();
|
||||
|
@ -862,8 +1021,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
|
||||
debug!("visit_lifetime(lifetime_ref={:?})", lifetime_ref);
|
||||
if lifetime_ref.is_elided() {
|
||||
self.resolve_elided_lifetimes(vec![lifetime_ref]);
|
||||
return;
|
||||
|
@ -897,7 +1056,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
|
||||
check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params);
|
||||
if !self.trait_definition_only {
|
||||
check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params);
|
||||
}
|
||||
for param in generics.params {
|
||||
match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {}
|
||||
|
@ -1224,56 +1385,53 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap<Vec<ObjectLifetimeDefault>> {
|
||||
let mut map = HirIdMap::default();
|
||||
for item in tcx.hir().krate().items.values() {
|
||||
match item.kind {
|
||||
hir::ItemKind::Struct(_, ref generics)
|
||||
| hir::ItemKind::Union(_, ref generics)
|
||||
| hir::ItemKind::Enum(_, ref generics)
|
||||
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
ref generics, impl_trait_fn: None, ..
|
||||
})
|
||||
| hir::ItemKind::TyAlias(_, ref generics)
|
||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
||||
let result = object_lifetime_defaults_for_item(tcx, generics);
|
||||
fn compute_object_lifetime_defaults(
|
||||
tcx: TyCtxt<'_>,
|
||||
item: &hir::Item<'_>,
|
||||
) -> Option<Vec<ObjectLifetimeDefault>> {
|
||||
match item.kind {
|
||||
hir::ItemKind::Struct(_, ref generics)
|
||||
| hir::ItemKind::Union(_, ref generics)
|
||||
| hir::ItemKind::Enum(_, ref generics)
|
||||
| hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
||||
| hir::ItemKind::TyAlias(_, ref generics)
|
||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
||||
let result = object_lifetime_defaults_for_item(tcx, generics);
|
||||
|
||||
// Debugging aid.
|
||||
let attrs = tcx.hir().attrs(item.hir_id());
|
||||
if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
|
||||
let object_lifetime_default_reprs: String = result
|
||||
.iter()
|
||||
.map(|set| match *set {
|
||||
Set1::Empty => "BaseDefault".into(),
|
||||
Set1::One(Region::Static) => "'static".into(),
|
||||
Set1::One(Region::EarlyBound(mut i, _, _)) => generics
|
||||
.params
|
||||
.iter()
|
||||
.find_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if i == 0 {
|
||||
return Some(param.name.ident().to_string().into());
|
||||
}
|
||||
i -= 1;
|
||||
None
|
||||
// Debugging aid.
|
||||
let attrs = tcx.hir().attrs(item.hir_id());
|
||||
if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
|
||||
let object_lifetime_default_reprs: String = result
|
||||
.iter()
|
||||
.map(|set| match *set {
|
||||
Set1::Empty => "BaseDefault".into(),
|
||||
Set1::One(Region::Static) => "'static".into(),
|
||||
Set1::One(Region::EarlyBound(mut i, _, _)) => generics
|
||||
.params
|
||||
.iter()
|
||||
.find_map(|param| match param.kind {
|
||||
GenericParamKind::Lifetime { .. } => {
|
||||
if i == 0 {
|
||||
return Some(param.name.ident().to_string().into());
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap(),
|
||||
Set1::One(_) => bug!(),
|
||||
Set1::Many => "Ambiguous".into(),
|
||||
})
|
||||
.collect::<Vec<Cow<'static, str>>>()
|
||||
.join(",");
|
||||
tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
|
||||
}
|
||||
|
||||
map.insert(item.hir_id(), result);
|
||||
i -= 1;
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap(),
|
||||
Set1::One(_) => bug!(),
|
||||
Set1::Many => "Ambiguous".into(),
|
||||
})
|
||||
.collect::<Vec<Cow<'static, str>>>()
|
||||
.join(",");
|
||||
tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
|
||||
}
|
||||
_ => {}
|
||||
|
||||
Some(result)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
map
|
||||
}
|
||||
|
||||
/// Scan the bounds and where-clauses on parameters to extract bounds
|
||||
|
@ -1392,15 +1550,20 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
trait_ref_hack: self.trait_ref_hack,
|
||||
is_in_fn_syntax: self.is_in_fn_syntax,
|
||||
is_in_const_generic: self.is_in_const_generic,
|
||||
trait_definition_only: self.trait_definition_only,
|
||||
labels_in_fn,
|
||||
xcrate_object_lifetime_defaults,
|
||||
lifetime_uses,
|
||||
missing_named_lifetime_spots,
|
||||
};
|
||||
debug!("entering scope {:?}", this.scope);
|
||||
f(self.scope, &mut this);
|
||||
this.check_uses_for_lifetimes_defined_by_scope();
|
||||
debug!("exiting scope {:?}", this.scope);
|
||||
let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
|
||||
{
|
||||
let _enter = span.enter();
|
||||
f(self.scope, &mut this);
|
||||
if !self.trait_definition_only {
|
||||
this.check_uses_for_lifetimes_defined_by_scope();
|
||||
}
|
||||
}
|
||||
self.labels_in_fn = this.labels_in_fn;
|
||||
self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
|
||||
self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
|
||||
|
@ -1859,7 +2022,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Check for fn-syntax conflicts with in-band lifetime definitions
|
||||
if self.is_in_fn_syntax {
|
||||
if !self.trait_definition_only && self.is_in_fn_syntax {
|
||||
match def {
|
||||
Region::EarlyBound(_, _, LifetimeDefOrigin::InBand)
|
||||
| Region::LateBound(_, _, LifetimeDefOrigin::InBand) => {
|
||||
|
@ -1991,47 +2154,47 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
};
|
||||
|
||||
let map = &self.map;
|
||||
let unsubst = if let Some(def_id) = def_id.as_local() {
|
||||
let set_to_region = |set: &ObjectLifetimeDefault| match *set {
|
||||
Set1::Empty => {
|
||||
if in_body {
|
||||
None
|
||||
} else {
|
||||
Some(Region::Static)
|
||||
}
|
||||
}
|
||||
Set1::One(r) => {
|
||||
let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
|
||||
GenericArg::Lifetime(lt) => Some(lt),
|
||||
_ => None,
|
||||
});
|
||||
r.subst(lifetimes, map)
|
||||
}
|
||||
Set1::Many => None,
|
||||
};
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
let id = self.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
&map.object_lifetime_defaults[&id]
|
||||
self.tcx.object_lifetime_defaults(id).unwrap().iter().map(set_to_region).collect()
|
||||
} else {
|
||||
let tcx = self.tcx;
|
||||
self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| {
|
||||
tcx.generics_of(def_id)
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamDefKind::Type { object_lifetime_default, .. } => {
|
||||
Some(object_lifetime_default)
|
||||
}
|
||||
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
};
|
||||
debug!("visit_segment_args: unsubst={:?}", unsubst);
|
||||
unsubst
|
||||
.iter()
|
||||
.map(|set| match *set {
|
||||
Set1::Empty => {
|
||||
if in_body {
|
||||
None
|
||||
} else {
|
||||
Some(Region::Static)
|
||||
}
|
||||
}
|
||||
Set1::One(r) => {
|
||||
let lifetimes = generic_args.args.iter().filter_map(|arg| match arg {
|
||||
GenericArg::Lifetime(lt) => Some(lt),
|
||||
_ => None,
|
||||
});
|
||||
r.subst(lifetimes, map)
|
||||
}
|
||||
Set1::Many => None,
|
||||
})
|
||||
.collect()
|
||||
self.xcrate_object_lifetime_defaults
|
||||
.entry(def_id)
|
||||
.or_insert_with(|| {
|
||||
tcx.generics_of(def_id)
|
||||
.params
|
||||
.iter()
|
||||
.filter_map(|param| match param.kind {
|
||||
GenericParamDefKind::Type { object_lifetime_default, .. } => {
|
||||
Some(object_lifetime_default)
|
||||
}
|
||||
GenericParamDefKind::Lifetime
|
||||
| GenericParamDefKind::Const { .. } => None,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.iter()
|
||||
.map(set_to_region)
|
||||
.collect()
|
||||
}
|
||||
});
|
||||
|
||||
debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults);
|
||||
|
@ -2092,12 +2255,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn visit_fn_like_elision(
|
||||
&mut self,
|
||||
inputs: &'tcx [hir::Ty<'tcx>],
|
||||
output: Option<&'tcx hir::Ty<'tcx>>,
|
||||
) {
|
||||
debug!("visit_fn_like_elision: enter");
|
||||
let arg_scope = Scope::Elision { elide: Elide::FreshLateAnon(Cell::new(0)), s: self.scope };
|
||||
self.with(arg_scope, |_, this| {
|
||||
for input in inputs {
|
||||
|
@ -2110,7 +2273,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
None => return,
|
||||
};
|
||||
|
||||
debug!("visit_fn_like_elision: determine output");
|
||||
debug!("determine output");
|
||||
|
||||
// Figure out if there's a body we can get argument names from,
|
||||
// and whether there's a `self` argument (treated specially).
|
||||
|
@ -2276,11 +2439,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
Elide::Error(arg_lifetimes)
|
||||
};
|
||||
|
||||
debug!("visit_fn_like_elision: elide={:?}", elide);
|
||||
debug!(?elide);
|
||||
|
||||
let scope = Scope::Elision { elide, s: self.scope };
|
||||
self.with(scope, |_, this| this.visit_ty(output));
|
||||
debug!("visit_fn_like_elision: exit");
|
||||
|
||||
struct GatherLifetimes<'a> {
|
||||
map: &'a NamedRegionMap,
|
||||
|
@ -2743,12 +2905,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
|
||||
debug!(
|
||||
"insert_lifetime: {} resolved to {:?} span={:?}",
|
||||
self.tcx.hir().node_to_string(lifetime_ref.hir_id),
|
||||
def,
|
||||
self.tcx.sess.source_map().span_to_string(lifetime_ref.span)
|
||||
node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
|
||||
span = ?self.tcx.sess.source_map().span_to_string(lifetime_ref.span)
|
||||
);
|
||||
self.map.defs.insert(lifetime_ref.hir_id, def);
|
||||
|
||||
|
@ -2762,12 +2923,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
| Region::EarlyBound(_, def_id, _) => {
|
||||
// A lifetime declared by the user.
|
||||
let track_lifetime_uses = self.track_lifetime_uses();
|
||||
debug!("insert_lifetime: track_lifetime_uses={}", track_lifetime_uses);
|
||||
debug!(?track_lifetime_uses);
|
||||
if track_lifetime_uses && !self.lifetime_uses.contains_key(&def_id) {
|
||||
debug!("insert_lifetime: first use of {:?}", def_id);
|
||||
debug!("first use of {:?}", def_id);
|
||||
self.lifetime_uses.insert(def_id, LifetimeUseSet::One(lifetime_ref));
|
||||
} else {
|
||||
debug!("insert_lifetime: many uses of {:?}", def_id);
|
||||
debug!("many uses of {:?}", def_id);
|
||||
self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
pub fn ast_region_to_region(
|
||||
&self,
|
||||
lifetime: &hir::Lifetime,
|
||||
|
@ -237,6 +238,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
None => {
|
||||
self.re_infer(def, lifetime.span).unwrap_or_else(|| {
|
||||
debug!(?lifetime, "unelided lifetime in signature");
|
||||
|
||||
// This indicates an illegal lifetime
|
||||
// elision. `resolve_lifetime` should have
|
||||
// reported an error in this case -- but if
|
||||
|
@ -2173,9 +2176,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
|
||||
/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
|
||||
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
|
||||
#[tracing::instrument(level = "debug", skip(self))]
|
||||
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
|
||||
debug!("ast_ty_to_ty(id={:?}, ast_ty={:?} ty_ty={:?})", ast_ty.hir_id, ast_ty, ast_ty.kind);
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
||||
let result_ty = match ast_ty.kind {
|
||||
|
@ -2185,7 +2187,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
hir::TyKind::Rptr(ref region, ref mt) => {
|
||||
let r = self.ast_region_to_region(region, None);
|
||||
debug!("ast_ty_to_ty: r={:?}", r);
|
||||
debug!(?r);
|
||||
let t = self.ast_ty_to_ty_inner(&mt.ty, true);
|
||||
tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
|
||||
}
|
||||
|
@ -2209,7 +2211,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
|
||||
}
|
||||
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
|
||||
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
|
||||
debug!(?maybe_qself, ?path);
|
||||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
|
||||
self.res_to_ty(opt_self_ty, path, false)
|
||||
}
|
||||
|
@ -2225,7 +2227,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
}
|
||||
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
||||
debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
|
||||
debug!(?qself, ?segment);
|
||||
let ty = self.ast_ty_to_ty(qself);
|
||||
|
||||
let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.kind {
|
||||
|
@ -2270,7 +2272,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
hir::TyKind::Err => tcx.ty_error(),
|
||||
};
|
||||
|
||||
debug!("ast_ty_to_ty: result_ty={:?}", result_ty);
|
||||
debug!(?result_ty);
|
||||
|
||||
self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
|
||||
result_ty
|
||||
|
|
|
@ -23,17 +23,6 @@ LL | A(u8),
|
|||
LL | B(&'a bool),
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:10:14
|
||||
|
|
||||
LL | type MyStr = &str;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type MyStr<'a> = &'a str;
|
||||
| ^^^^ ^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:17:10
|
||||
|
|
||||
|
@ -61,6 +50,17 @@ LL |
|
|||
LL | buzz: Buzz<'a, 'a>,
|
||||
|
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/E0106.rs:10:14
|
||||
|
|
||||
LL | type MyStr = &str;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type MyStr<'a> = &'a str;
|
||||
| ^^^^ ^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0106`.
|
||||
|
|
|
@ -1,3 +1,87 @@
|
|||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:50:14
|
||||
|
|
||||
LL | impl MyTrait<'a> for Y<&'a u8> {
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:50:25
|
||||
|
|
||||
LL | impl MyTrait<'a> for Y<&'a u8> {
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:53:31
|
||||
|
|
||||
LL | fn my_lifetime(&self) -> &'a u8 { self.0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | impl<'a> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | fn my_lifetime<'a>(&self) -> &'a u8 { self.0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:55:27
|
||||
|
|
||||
LL | fn any_lifetime() -> &'b u8 { &0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn any_lifetime<'b>() -> &'b u8 { &0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:57:27
|
||||
|
|
||||
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:57:40
|
||||
|
|
||||
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'x`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:3:12
|
||||
|
|
||||
|
@ -142,90 +226,6 @@ help: consider introducing lifetime `'b` here
|
|||
LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8;
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:50:14
|
||||
|
|
||||
LL | impl MyTrait<'a> for Y<&'a u8> {
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:50:25
|
||||
|
|
||||
LL | impl MyTrait<'a> for Y<&'a u8> {
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `<'a>`
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:53:31
|
||||
|
|
||||
LL | fn my_lifetime(&self) -> &'a u8 { self.0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | impl<'a> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'a` here
|
||||
|
|
||||
LL | fn my_lifetime<'a>(&self) -> &'a u8 { self.0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:55:27
|
||||
|
|
||||
LL | fn any_lifetime() -> &'b u8 { &0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn any_lifetime<'b>() -> &'b u8 { &0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:57:27
|
||||
|
|
||||
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/feature-gate-in_band_lifetimes.rs:57:40
|
||||
|
|
||||
LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | impl<'b> MyTrait<'a> for Y<&'a u8> {
|
||||
| ^^^^
|
||||
help: consider introducing lifetime `'b` here
|
||||
|
|
||||
LL | fn borrowed_lifetime<'b>(&'b self) -> &'b u8 { &*self.0 }
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
|
|
@ -14,14 +14,6 @@ LL | impl<T> NoShadowT<T> for Option<T> {
|
|||
LL | type Bar<T> = i32;
|
||||
| ^ already used
|
||||
|
||||
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
||||
--> $DIR/shadowing.rs:5:14
|
||||
|
|
||||
LL | trait Shadow<'a> {
|
||||
| -- first declared here
|
||||
LL | type Bar<'a>;
|
||||
| ^^ lifetime `'a` already in scope
|
||||
|
||||
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
||||
--> $DIR/shadowing.rs:14:14
|
||||
|
|
||||
|
@ -30,6 +22,14 @@ LL | impl<'a> NoShadow<'a> for &'a u32 {
|
|||
LL | type Bar<'a> = i32;
|
||||
| ^^ lifetime `'a` already in scope
|
||||
|
||||
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
||||
--> $DIR/shadowing.rs:5:14
|
||||
|
|
||||
LL | trait Shadow<'a> {
|
||||
| -- first declared here
|
||||
LL | type Bar<'a>;
|
||||
| ^^ lifetime `'a` already in scope
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0403, E0496.
|
||||
|
|
|
@ -4,6 +4,17 @@ error[E0637]: `&` without an explicit lifetime name cannot be used here
|
|||
LL | fn should_error<T>() where T : Into<&u32> {}
|
||||
| ^ explicit lifetime name needed here
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:17
|
||||
|
|
||||
LL | fn bar<'b, L: X<&'b Nested<i32>>>(){}
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider using the `'b` lifetime
|
||||
|
|
||||
LL | fn bar<'b, L: X<'b, &'b Nested<i32>>>(){}
|
||||
| ^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:21
|
||||
|
|
||||
|
@ -22,17 +33,6 @@ help: consider using one of the available lifetimes here
|
|||
LL | fn foo<'b, L: X<'lifetime, &'b Nested<K>>>();
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:17
|
||||
|
|
||||
LL | fn bar<'b, L: X<&'b Nested<i32>>>(){}
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider using the `'b` lifetime
|
||||
|
|
||||
LL | fn bar<'b, L: X<'b, &'b Nested<i32>>>(){}
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0637.
|
||||
|
|
|
@ -1,36 +1,3 @@
|
|||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:44:14
|
||||
|
|
||||
LL | type A = Ty;
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type A<'a> = Ty<'a>;
|
||||
| ^^^^ ^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:54:17
|
||||
|
|
||||
LL | type C = Ty<usize>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type C<'a> = Ty<'a, usize>;
|
||||
| ^^^^ ^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:100:22
|
||||
|
|
||||
LL | type B = Box<dyn GenericLifetime>;
|
||||
| ^^^^^^^^^^^^^^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type B<'a> = Box<dyn GenericLifetime<'a>>;
|
||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied
|
||||
--> $DIR/wrong-number-of-args.rs:6:14
|
||||
|
|
||||
|
@ -165,6 +132,17 @@ help: use angle brackets to add missing type argument
|
|||
LL | type A = Ty<T>;
|
||||
| ^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:44:14
|
||||
|
|
||||
LL | type A = Ty;
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type A<'a> = Ty<'a>;
|
||||
| ^^^^ ^^^^^^
|
||||
|
||||
error[E0107]: this struct takes 1 type argument but 0 type arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:50:14
|
||||
|
|
||||
|
@ -181,6 +159,17 @@ help: add missing type argument
|
|||
LL | type B = Ty<'static, T>;
|
||||
| ^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:54:17
|
||||
|
|
||||
LL | type C = Ty<usize>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type C<'a> = Ty<'a, usize>;
|
||||
| ^^^^ ^^^
|
||||
|
||||
error[E0107]: missing generics for struct `type_and_type_and_type::Ty`
|
||||
--> $DIR/wrong-number-of-args.rs:64:14
|
||||
|
|
||||
|
@ -243,6 +232,17 @@ note: trait defined here, with 0 type parameters
|
|||
LL | trait NonGeneric {
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:100:22
|
||||
|
|
||||
LL | type B = Box<dyn GenericLifetime>;
|
||||
| ^^^^^^^^^^^^^^^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type B<'a> = Box<dyn GenericLifetime<'a>>;
|
||||
| ^^^^ ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:104:22
|
||||
|
|
||||
|
|
|
@ -7,7 +7,7 @@ fn foo(x: &u32) {
|
|||
|
||||
fn foo2(x: &u32) {}
|
||||
fn bar() {
|
||||
let y: fn(&'test u32) = foo2; //~ ERROR use of undeclared lifetime
|
||||
let y: fn(&'test u32) = foo2;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -6,22 +6,6 @@ LL | fn foo(x: &u32) {
|
|||
LL | let y: &'test u32 = x;
|
||||
| ^^^^^ undeclared lifetime
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'test`
|
||||
--> $DIR/no_introducing_in_band_in_locals.rs:10:16
|
||||
|
|
||||
LL | let y: fn(&'test u32) = foo2;
|
||||
| ^^^^^ undeclared lifetime
|
||||
|
|
||||
= note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
|
||||
help: consider introducing lifetime `'test` here
|
||||
|
|
||||
LL | fn bar<'test>() {
|
||||
| ^^^^^^^
|
||||
help: consider making the type lifetime-generic with a new `'test` lifetime
|
||||
|
|
||||
LL | let y: for<'test> fn(&'test u32) = foo2;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
|
||||
|
|
||||
LL | struct Test {
|
||||
| - help: consider introducing lifetime `'b` here: `<'b>`
|
||||
LL | a: &'b str,
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:13:13
|
||||
|
|
||||
|
@ -14,16 +24,6 @@ help: consider introducing lifetime `'b` here
|
|||
LL | fn foo<'b>(&'b self) {}
|
||||
| ^^^^
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
|
||||
|
|
||||
LL | struct Test {
|
||||
| - help: consider introducing lifetime `'b` here: `<'b>`
|
||||
LL | a: &'b str,
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
|
||||
|
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
fn main() {
|
||||
0.clone::<'a>(); //~ ERROR use of undeclared lifetime name `'a`
|
||||
//~^ WARNING cannot specify lifetime arguments
|
||||
//~| WARNING this was previously accepted
|
||||
}
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
|
||||
--> $DIR/method-call-lifetime-args-unresolved.rs:2:15
|
||||
|
|
||||
LL | 0.clone::<'a>();
|
||||
| ^^
|
||||
|
|
||||
::: $SRC_DIR/core/src/clone.rs:LL:COL
|
||||
|
|
||||
LL | fn clone(&self) -> Self;
|
||||
| - the late bound lifetime parameter is introduced here
|
||||
|
|
||||
= note: `#[warn(late_bound_lifetime_arguments)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/method-call-lifetime-args-unresolved.rs:2:15
|
||||
|
|
||||
|
@ -8,6 +23,6 @@ LL | 0.clone::<'a>();
|
|||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
|
|
@ -8,7 +8,7 @@ struct ChunkingIterator<T, S: 'static + Iterator<Item = T>> {
|
|||
impl<T, S: Iterator<Item = T>> Iterator for ChunkingIterator<T, S> {
|
||||
type Item = IteratorChunk<T, S>; //~ ERROR missing lifetime
|
||||
|
||||
fn next(&mut self) -> Option<IteratorChunk<T, S>> { //~ ERROR `impl`
|
||||
fn next(&mut self) -> Option<IteratorChunk<T, S>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,22 +9,6 @@ help: consider introducing a named lifetime parameter
|
|||
LL | type Item<'a> = IteratorChunk<'a, T, S>;
|
||||
| ^^^^ ^^^
|
||||
|
||||
error: `impl` item signature doesn't match `trait` item signature
|
||||
--> $DIR/issue-74918-missing-lifetime.rs:11:5
|
||||
|
|
||||
LL | fn next(&mut self) -> Option<IteratorChunk<T, S>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'_, T, S>>`
|
||||
|
|
||||
::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||
|
|
||||
LL | fn next(&mut self) -> Option<Self::Item>;
|
||||
| ----------------------------------------- expected `fn(&mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, _, _>>`
|
||||
|
|
||||
= note: expected `fn(&mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'static, _, _>>`
|
||||
found `fn(&mut ChunkingIterator<T, S>) -> Option<IteratorChunk<'_, _, _>>`
|
||||
= help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
|
||||
= help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0106`.
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:28:13
|
||||
|
|
||||
LL | enum E {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | E1(&'a isize)
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:31:13
|
||||
|
|
||||
LL | struct S {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | f: &'a isize
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/regions-name-undeclared.rs:16:24
|
||||
|
|
||||
|
@ -56,26 +76,6 @@ LL | type X = Option<&'a isize>;
|
|||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:28:13
|
||||
|
|
||||
LL | enum E {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | E1(&'a isize)
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:31:13
|
||||
|
|
||||
LL | struct S {
|
||||
| - help: consider introducing lifetime `'a` here: `<'a>`
|
||||
LL | f: &'a isize
|
||||
| ^^ undeclared lifetime
|
||||
|
|
||||
= help: if you want to experiment with in-band lifetime bindings, add `#![feature(in_band_lifetimes)]` to the crate attributes
|
||||
|
||||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/regions-name-undeclared.rs:33:14
|
||||
|
|
||||
|
|
|
@ -1,92 +1,11 @@
|
|||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:37:11
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:36:11
|
||||
|
|
||||
LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `'a,`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:15:37
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
| - ^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
|
||||
| |
|
||||
| let's call the lifetime of this reference `'1`
|
||||
|
|
||||
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
error: aborting due to previous error
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:25:37
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the function body at 25:26...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:25:26
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:47:45
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the function body at 47:34...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:47:34
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:59:58
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the method body at 59:47...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:59:47
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:68:45
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the function body at 68:34...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:68:34
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ^^^^^^
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `dest`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:73:5
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
|
||||
...
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^ lifetime `'a` required
|
||||
|
||||
error[E0309]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:79:44
|
||||
|
|
||||
LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `G: 'a`...
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0309, E0621.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
|
|
@ -16,14 +16,13 @@ fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
|||
where
|
||||
G: Get<T>
|
||||
{
|
||||
move || { //~ ERROR `dest`
|
||||
move || {
|
||||
*dest = g.get();
|
||||
}
|
||||
}
|
||||
|
||||
// After applying suggestion for `foo`:
|
||||
fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
where
|
||||
G: Get<T>
|
||||
{
|
||||
|
@ -45,7 +44,6 @@ where
|
|||
|
||||
// After applying suggestion for `baz`:
|
||||
fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
where
|
||||
G: Get<T>
|
||||
{
|
||||
|
@ -57,7 +55,6 @@ where
|
|||
// Same as above, but show that we pay attention to lifetime names from parent item
|
||||
impl<'a> Foo {
|
||||
fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
move || {
|
||||
*dest = g.get();
|
||||
}
|
||||
|
@ -66,7 +63,6 @@ impl<'a> Foo {
|
|||
|
||||
// After applying suggestion for `qux`:
|
||||
fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
//~^ ERROR explicit lifetime required in the type of `dest`
|
||||
where
|
||||
G: Get<T>
|
||||
{
|
||||
|
@ -77,7 +73,6 @@ where
|
|||
|
||||
// Potential incorrect attempt:
|
||||
fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
//~^ ERROR the parameter type `G` may not live long enough
|
||||
where
|
||||
G: Get<T>
|
||||
{
|
||||
|
|
|
@ -1,112 +1,11 @@
|
|||
error[E0261]: use of undeclared lifetime name `'a`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:37:11
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:36:11
|
||||
|
|
||||
LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| - ^^ undeclared lifetime
|
||||
| |
|
||||
| help: consider introducing lifetime `'a` here: `'a,`
|
||||
|
||||
error[E0759]: `dest` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
| ------ this data with an anonymous lifetime `'_`...
|
||||
...
|
||||
LL | / move || {
|
||||
LL | | *dest = g.get();
|
||||
LL | | }
|
||||
| |_____^ ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:15:37
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
|
||||
| ^^^^^^^^^^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `dest`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^
|
||||
error: aborting due to previous error
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:25:37
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the function body at 25:26...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:25:26
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:30:5: 32:6]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:25:37
|
||||
|
|
||||
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL | fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ^^^^^ ^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:47:45
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the function body at 47:34...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:47:34
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:52:5: 54:6]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:47:45
|
||||
|
|
||||
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL | fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b
|
||||
| ^^^ ^^^^^^^ ^^^^
|
||||
|
||||
error[E0311]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:59:58
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the parameter type `G` must be valid for the anonymous lifetime defined on the method body at 59:47...
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:59:47
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^
|
||||
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:61:9: 63:10]` will meet its required lifetime bounds
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:59:58
|
||||
|
|
||||
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: consider introducing an explicit lifetime bound
|
||||
|
|
||||
LL | fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'c {
|
||||
| ^^^ ^^^^^^^ ^^^^
|
||||
|
||||
error[E0621]: explicit lifetime required in the type of `dest`
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:68:45
|
||||
|
|
||||
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
|
||||
| ------ ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
|
||||
| |
|
||||
| help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
|
||||
|
||||
error[E0309]: the parameter type `G` may not live long enough
|
||||
--> $DIR/missing-lifetimes-in-signature.rs:79:44
|
||||
|
|
||||
LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
|
||||
| - ^^^^^^^^^^^^^^^^^^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:84:5: 86:6]` will meet its required lifetime bounds
|
||||
| |
|
||||
| help: consider adding an explicit lifetime bound...: `G: 'a`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0309, E0621, E0759.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
|
|
@ -142,30 +142,6 @@ help: consider using the `'static` lifetime
|
|||
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-specifier.rs:50:44
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-specifier.rs:50:44
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0107]: this union takes 2 lifetime arguments but only 1 lifetime argument was supplied
|
||||
--> $DIR/missing-lifetime-specifier.rs:43:44
|
||||
|
|
||||
|
@ -256,6 +232,18 @@ help: add missing lifetime argument
|
|||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-specifier.rs:50:44
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0107]: this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
|
||||
--> $DIR/missing-lifetime-specifier.rs:50:45
|
||||
|
|
||||
|
@ -274,6 +262,18 @@ help: add missing lifetime argument
|
|||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/missing-lifetime-specifier.rs:50:44
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
help: consider using the `'static` lifetime
|
||||
|
|
||||
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
|
||||
| ^^^^^^^^
|
||||
|
||||
error[E0107]: this trait takes 2 lifetime arguments but only 1 lifetime argument was supplied
|
||||
--> $DIR/missing-lifetime-specifier.rs:50:45
|
||||
|
|
||||
|
|
Loading…
Add table
Reference in a new issue