diff options
| author | bors <bors@rust-lang.org> | 2022-06-03 15:26:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-06-03 15:26:06 +0000 |
| commit | 9a74608543d499bcc7dd505e195e8bfab9447315 (patch) | |
| tree | efcb4d4a2294dcae517f2d690d3c544df5ce7511 /compiler/rustc_resolve | |
| parent | e40d5e83dc133d093c22c7ff016b10daa4f40dcf (diff) | |
| parent | 5549d50ccf5c9f505672d9a1eb524e77aac95842 (diff) | |
| download | rust-9a74608543d499bcc7dd505e195e8bfab9447315.tar.gz rust-9a74608543d499bcc7dd505e195e8bfab9447315.zip | |
Auto merge of #97694 - Dylan-DPC:rollup-2yxo7ce, r=Dylan-DPC
Rollup of 3 pull requests Successful merges: - #97415 (Compute `is_late_bound_map` query separately from lifetime resolution) - #97471 (Provide more context when denying invalid type params ) - #97681 (Add more eslint checks) Failed merges: - #97446 (Make hir().get_generics and generics_of consistent.) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 233 |
2 files changed, 108 insertions, 154 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 9213652e35f..cb39eb5416b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -13,7 +13,7 @@ use rustc_ast::{ }; use rustc_ast_lowering::ResolverAstLowering; use rustc_ast_pretty::pprust::path_segment_to_string; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, @@ -21,7 +21,7 @@ use rustc_errors::{ use rustc_hir as hir; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; -use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; use rustc_session::lint; use rustc_session::parse::feature_err; @@ -2082,7 +2082,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { /// Returns whether to add `'static` lifetime to the suggested lifetime list. pub(crate) fn report_elision_failure( - &mut self, + &self, diag: &mut Diagnostic, params: &[ElisionFailureInfo], ) -> bool { @@ -2187,10 +2187,27 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { &self, err: &mut Diagnostic, mut spans_with_counts: Vec<(Span, usize)>, - lifetime_names: &FxHashSet<Symbol>, - lifetime_spans: Vec<Span>, - params: &[ElisionFailureInfo], + in_scope_lifetimes: FxIndexSet<LocalDefId>, + params: Option<&[ElisionFailureInfo]>, ) { + let (mut lifetime_names, lifetime_spans): (FxHashSet<_>, Vec<_>) = in_scope_lifetimes + .iter() + .filter_map(|def_id| { + let name = self.tcx.item_name(def_id.to_def_id()); + let span = self.tcx.def_ident_span(def_id.to_def_id())?; + Some((name, span)) + }) + .filter(|&(n, _)| n != kw::UnderscoreLifetime) + .unzip(); + + if let Some(params) = params { + // If there's no lifetime available, suggest `'static`. + if self.report_elision_failure(err, params) && lifetime_names.is_empty() { + lifetime_names.insert(kw::StaticLifetime); + } + } + let params = params.unwrap_or(&[]); + let snippets: Vec<Option<String>> = spans_with_counts .iter() .map(|(span, _)| self.tcx.sess.source_map().span_to_snippet(*span).ok()) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 59c2db25b8e..11f80b314d7 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -8,19 +8,19 @@ use crate::late::diagnostics::{ForLifetimeSpanType, MissingLifetimeSpot}; use rustc_ast::walk_list; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefIdMap, LocalDefId}; use rustc_hir::hir_id::ItemLocalId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node, ParamName}; -use rustc_hir::{GenericParamKind, HirIdMap, HirIdSet}; +use rustc_hir::{GenericArg, GenericParam, LifetimeName, Node}; +use rustc_hir::{GenericParamKind, HirIdMap}; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::*; -use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; +use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::{kw, sym, Ident}; @@ -33,9 +33,9 @@ use std::mem::take; use tracing::{debug, span, Level}; trait RegionExt { - fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region); + fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region); - fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region); + fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region); fn late_anon(named_late_bound_vars: u32, index: &Cell<u32>) -> Region; @@ -51,22 +51,22 @@ trait RegionExt { } impl RegionExt for Region { - fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (ParamName, Region) { + fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region) { let i = *index; *index += 1; let def_id = hir_map.local_def_id(param.hir_id); debug!("Region::early: index={} def_id={:?}", i, def_id); - (param.name.normalize_to_macros_2_0(), Region::EarlyBound(i, def_id.to_def_id())) + (def_id, Region::EarlyBound(i, def_id.to_def_id())) } - fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (ParamName, Region) { + fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) { let depth = ty::INNERMOST; let def_id = hir_map.local_def_id(param.hir_id); debug!( "Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}", idx, param, depth, def_id, ); - (param.name.normalize_to_macros_2_0(), Region::LateBound(depth, idx, def_id.to_def_id())) + (def_id, Region::LateBound(depth, idx, def_id.to_def_id())) } fn late_anon(named_late_bound_vars: u32, index: &Cell<u32>) -> Region { @@ -134,11 +134,6 @@ struct NamedRegionMap { // `Region` describing how that region is bound defs: HirIdMap<Region>, - // the set of lifetime def ids that are late-bound; a region can - // be late-bound if (a) it does NOT appear in a where-clause and - // (b) it DOES appear in the arguments. - late_bound: HirIdSet, - // Maps relevant hir items to the bound vars on them. These include: // - function defs // - function pointers @@ -178,7 +173,7 @@ enum Scope<'a> { Binder { /// We use an IndexMap here because we want these lifetimes in order /// for diagnostics. - lifetimes: FxIndexMap<hir::ParamName, Region>, + lifetimes: FxIndexMap<LocalDefId, Region>, /// if we extend this scope with another scope, what is the next index /// we should use for an early-bound region? @@ -402,7 +397,7 @@ fn resolve_lifetimes_trait_definition( tcx: TyCtxt<'_>, local_def_id: LocalDefId, ) -> ResolveLifetimes { - convert_named_region_map(tcx, do_resolve(tcx, local_def_id, true, false)) + convert_named_region_map(do_resolve(tcx, local_def_id, true, false)) } /// Computes the `ResolveLifetimes` map that contains data for an entire `Item`. @@ -410,7 +405,7 @@ fn resolve_lifetimes_trait_definition( /// `named_region_map`, `is_late_bound_map`, etc. #[tracing::instrument(level = "debug", skip(tcx))] fn resolve_lifetimes(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> ResolveLifetimes { - convert_named_region_map(tcx, do_resolve(tcx, local_def_id, false, false)) + convert_named_region_map(do_resolve(tcx, local_def_id, false, false)) } fn do_resolve( @@ -422,7 +417,6 @@ fn do_resolve( let item = tcx.hir().expect_item(local_def_id); let mut named_region_map = NamedRegionMap { defs: Default::default(), - late_bound: Default::default(), late_bound_vars: Default::default(), scope_for_path: with_scope_for_path.then(|| Default::default()), }; @@ -439,18 +433,13 @@ fn do_resolve( named_region_map } -fn convert_named_region_map(tcx: TyCtxt<'_>, named_region_map: NamedRegionMap) -> ResolveLifetimes { +fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetimes { let mut rl = ResolveLifetimes::default(); for (hir_id, v) in named_region_map.defs { let map = rl.defs.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); } - for hir_id in named_region_map.late_bound { - let map = rl.late_bound.entry(hir_id.owner).or_default(); - let def_id = tcx.hir().local_def_id(hir_id); - map.insert(def_id); - } for (hir_id, v) in named_region_map.late_bound_vars { let map = rl.late_bound_vars.entry(hir_id.owner).or_default(); map.insert(hir_id.local_id, v); @@ -506,28 +495,6 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId { item } -fn is_late_bound_map<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, -) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> { - match tcx.def_kind(def_id) { - DefKind::AnonConst | DefKind::InlineConst => { - let mut def_id = tcx.local_parent(def_id); - // We search for the next outer anon const or fn here - // while skipping closures. - // - // Note that for `AnonConst` we still just recurse until we - // find a function body, but who cares :shrug: - while tcx.is_closure(def_id.to_def_id()) { - def_id = tcx.local_parent(def_id); - } - - tcx.is_late_bound_map(def_id) - } - _ => resolve_lifetimes_for(tcx, def_id).late_bound.get(&def_id).map(|lt| (def_id, lt)), - } -} - /// 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. @@ -554,10 +521,7 @@ fn get_lifetime_scopes_for_path(mut scope: &Scope<'_>) -> LifetimeScopeForPath { loop { match scope { Scope::Binder { lifetimes, s, .. } => { - available_lifetimes.extend(lifetimes.keys().filter_map(|p| match p { - hir::ParamName::Plain(ident) => Some(ident.name), - _ => None, - })); + available_lifetimes.extend(lifetimes.keys()); scope = s; } Scope::Body { s, .. } => { @@ -690,9 +654,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { _ => {} } match item.kind { - hir::ItemKind::Fn(ref sig, ref generics, _) => { + hir::ItemKind::Fn(_, ref generics, _) => { self.missing_named_lifetime_spots.push(generics.into()); - self.visit_early_late(None, item.hir_id(), &sig.decl, generics, |this| { + self.visit_early_late(None, item.hir_id(), generics, |this| { intravisit::walk_item(this, item); }); self.missing_named_lifetime_spots.pop(); @@ -734,13 +698,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { self.map.defs.insert(hir::HirId { owner, local_id }, *region); }); } - for (&owner, late_bound) in resolved_lifetimes.late_bound.iter() { - late_bound.iter().for_each(|&id| { - let hir_id = self.tcx.local_def_id_to_hir_id(id); - debug_assert_eq!(owner, hir_id.owner); - self.map.late_bound.insert(hir_id); - }); - } for (&owner, late_bound_vars) in resolved_lifetimes.late_bound_vars.iter() { @@ -810,8 +767,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { - hir::ForeignItemKind::Fn(ref decl, _, ref generics) => { - self.visit_early_late(None, item.hir_id(), decl, generics, |this| { + hir::ForeignItemKind::Fn(_, _, ref generics) => { + self.visit_early_late(None, item.hir_id(), generics, |this| { intravisit::walk_foreign_item(this, item); }) } @@ -841,7 +798,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }; self.missing_named_lifetime_spots .push(MissingLifetimeSpot::HigherRanked { span, span_type }); - let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) = c + let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = c .generic_params .iter() .filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. })) @@ -898,7 +855,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // cc #48468 self.resolve_elided_lifetimes(&[lifetime]) } - LifetimeName::Param(_) | LifetimeName::Static => { + LifetimeName::Param(..) | LifetimeName::Static => { // If the user wrote an explicit name, use that. self.visit_lifetime(lifetime); } @@ -1016,17 +973,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { for param in generics.params { match param.kind { GenericParamKind::Lifetime { .. } => { - let (name, reg) = Region::early(self.tcx.hir(), &mut index, ¶m); + let (def_id, reg) = Region::early(self.tcx.hir(), &mut index, ¶m); if let hir::ParamName::Plain(Ident { name: kw::UnderscoreLifetime, .. - }) = name + }) = param.name { // Pick the elided lifetime "definition" if one exists // and use it to make an elision scope. elision = Some(reg); } else { - lifetimes.insert(name, reg); + lifetimes.insert(def_id, reg); } } GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { @@ -1088,13 +1045,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { use self::hir::TraitItemKind::*; match trait_item.kind { - Fn(ref sig, _) => { + Fn(_, _) => { self.missing_named_lifetime_spots.push((&trait_item.generics).into()); let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(trait_item.hir_id())), trait_item.hir_id(), - &sig.decl, &trait_item.generics, |this| intravisit::walk_trait_item(this, trait_item), ); @@ -1156,13 +1112,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { use self::hir::ImplItemKind::*; match impl_item.kind { - Fn(ref sig, _) => { + Fn(..) => { self.missing_named_lifetime_spots.push((&impl_item.generics).into()); let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(impl_item.hir_id())), impl_item.hir_id(), - &sig.decl, &impl_item.generics, |this| intravisit::walk_impl_item(this, impl_item), ); @@ -1174,7 +1129,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let mut index = self.next_early_index(); let mut non_lifetime_count = 0; debug!("visit_ty: index = {}", index); - let lifetimes: FxIndexMap<hir::ParamName, Region> = generics + let lifetimes: FxIndexMap<LocalDefId, Region> = generics .params .iter() .filter_map(|param| match param.kind { @@ -1218,15 +1173,17 @@ 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) { - if lifetime_ref.is_elided() { - self.resolve_elided_lifetimes(&[lifetime_ref]); - return; - } - if lifetime_ref.is_static() { - self.insert_lifetime(lifetime_ref, Region::Static); - return; + match lifetime_ref.name { + hir::LifetimeName::ImplicitObjectLifetimeDefault + | hir::LifetimeName::Implicit + | hir::LifetimeName::Underscore => self.resolve_elided_lifetimes(&[lifetime_ref]), + hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), + hir::LifetimeName::Param(param_def_id, _) => { + self.resolve_lifetime_ref(param_def_id, lifetime_ref) + } + // If we've already reported an error, just ignore `lifetime_ref`. + hir::LifetimeName::Error => {} } - self.resolve_lifetime_ref(lifetime_ref); } fn visit_assoc_type_binding(&mut self, type_binding: &'tcx hir::TypeBinding<'_>) { @@ -1311,7 +1268,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { ref bound_generic_params, .. }) => { - let (lifetimes, binders): (FxIndexMap<hir::ParamName, Region>, Vec<_>) = + let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = bound_generic_params .iter() .filter(|param| { @@ -1433,7 +1390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let (mut binders, scope_type) = self.poly_trait_ref_binder_info(); let initial_bound_vars = binders.len() as u32; - let mut lifetimes: FxIndexMap<hir::ParamName, Region> = FxIndexMap::default(); + let mut lifetimes: FxIndexMap<LocalDefId, Region> = FxIndexMap::default(); let binders_iter = trait_ref .bound_generic_params .iter() @@ -1580,14 +1537,17 @@ fn object_lifetime_defaults_for_item<'tcx>( .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some((param.hir_id, hir::LifetimeName::Param(param.name))) + let param_def_id = tcx.hir().local_def_id(param.hir_id); + Some(( + param_def_id, + hir::LifetimeName::Param(param_def_id, param.name), + )) } _ => None, }) .enumerate() .find(|&(_, (_, lt_name))| lt_name == name) - .map_or(Set1::Many, |(i, (id, _))| { - let def_id = tcx.hir().local_def_id(id); + .map_or(Set1::Many, |(i, (def_id, _))| { Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id())) }) } @@ -1654,14 +1614,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { &mut self, parent_id: Option<LocalDefId>, hir_id: hir::HirId, - decl: &'tcx hir::FnDecl<'tcx>, generics: &'tcx hir::Generics<'tcx>, walk: F, ) where F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>), { - insert_late_bound_lifetimes(self.map, decl, generics); - // Find the start of nested early scopes, e.g., in methods. let mut next_early_index = 0; if let Some(parent_id) = parent_id { @@ -1680,12 +1637,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut non_lifetime_count = 0; let mut named_late_bound_vars = 0; - let lifetimes: FxIndexMap<hir::ParamName, Region> = generics + let lifetimes: FxIndexMap<LocalDefId, Region> = generics .params .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - if self.map.late_bound.contains(¶m.hir_id) { + if self.tcx.is_late_bound(param.hir_id) { let late_bound_idx = named_late_bound_vars; named_late_bound_vars += 1; Some(Region::late(late_bound_idx, self.tcx.hir(), param)) @@ -1706,7 +1663,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .iter() .filter(|param| { matches!(param.kind, GenericParamKind::Lifetime { .. }) - && self.map.late_bound.contains(¶m.hir_id) + && self.tcx.is_late_bound(param.hir_id) }) .enumerate() .map(|(late_bound_idx, param)| { @@ -1763,14 +1720,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.next_early_index_helper(false) } - fn resolve_lifetime_ref(&mut self, lifetime_ref: &'tcx hir::Lifetime) { - debug!("resolve_lifetime_ref(lifetime_ref={:?})", lifetime_ref); - - // If we've already reported an error, just ignore `lifetime_ref`. - if let LifetimeName::Error = lifetime_ref.name { - return; - } - + #[tracing::instrument(level = "debug", skip(self))] + fn resolve_lifetime_ref( + &mut self, + region_def_id: LocalDefId, + lifetime_ref: &'tcx hir::Lifetime, + ) { // Walk up the scope chain, tracking the number of fn scopes // that we pass through, until we find a lifetime with the // given name or we run out of scopes. @@ -1790,14 +1745,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } Scope::Binder { ref lifetimes, scope_type, s, .. } => { - match lifetime_ref.name { - LifetimeName::Param(param_name) => { - if let Some(&def) = lifetimes.get(¶m_name.normalize_to_macros_2_0()) - { - break Some(def.shifted(late_depth)); - } - } - _ => bug!("expected LifetimeName::Param"), + if let Some(&def) = lifetimes.get(®ion_def_id) { + break Some(def.shifted(late_depth)); } match scope_type { BinderScopeType::Normal => late_depth += 1, @@ -2473,8 +2422,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut late_depth = 0; let mut scope = self.scope; - let mut lifetime_names = FxHashSet::default(); - let mut lifetime_spans = vec![]; + let mut in_scope_lifetimes = FxIndexSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2484,12 +2432,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { s, ref lifetimes, scope_type, .. } => { // collect named lifetimes for suggestions - for name in lifetimes.keys() { - if let hir::ParamName::Plain(name) = name { - lifetime_names.insert(name.name); - lifetime_spans.push(name.span); - } - } + in_scope_lifetimes.extend(lifetimes.keys().copied()); match scope_type { BinderScopeType::Normal => late_depth += 1, BinderScopeType::Concatenating => {} @@ -2524,12 +2467,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { match scope { Scope::Binder { ref lifetimes, s, .. } => { // Collect named lifetimes for suggestions. - for name in lifetimes.keys() { - if let hir::ParamName::Plain(name) = name { - lifetime_names.insert(name.name); - lifetime_spans.push(name.span); - } - } + in_scope_lifetimes.extend(lifetimes.keys().copied()); scope = s; } Scope::ObjectLifetimeDefault { ref s, .. } @@ -2574,19 +2512,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let mut err = self.report_missing_lifetime_specifiers(spans.clone(), lifetime_refs.len()); - if let Some(params) = error { - // If there's no lifetime available, suggest `'static`. - if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() { - lifetime_names.insert(kw::StaticLifetime); - } - } - self.add_missing_lifetime_specifiers_label( &mut err, spans_with_counts, - &lifetime_names, - lifetime_spans, - error.unwrap_or(&[]), + in_scope_lifetimes, + error, ); err.emit(); } @@ -2638,7 +2568,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } /// Detects late-bound lifetimes and inserts them into -/// `map.late_bound`. +/// `late_bound`. /// /// A region declared on a fn is **late-bound** if: /// - it is constrained by an argument type; @@ -2647,12 +2577,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// "Constrained" basically means that it appears in any type but /// not amongst the inputs to a projection. In other words, `<&'a /// T as Trait<''b>>::Foo` does not constrain `'a` or `'b`. -#[tracing::instrument(level = "debug", skip(map))] -fn insert_late_bound_lifetimes( - map: &mut NamedRegionMap, - decl: &hir::FnDecl<'_>, - generics: &hir::Generics<'_>, -) { +fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxHashSet<LocalDefId>> { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let decl = tcx.hir().fn_decl_by_hir_id(hir_id)?; + let generics = tcx.hir().get_generics(def_id)?; + + let mut late_bound = FxHashSet::default(); + let mut constrained_by_input = ConstrainedCollector::default(); for arg_ty in decl.inputs { constrained_by_input.visit_ty(arg_ty); @@ -2683,30 +2614,32 @@ fn insert_late_bound_lifetimes( hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => continue, } - let lt_name = hir::LifetimeName::Param(param.name.normalize_to_macros_2_0()); + let param_def_id = tcx.hir().local_def_id(param.hir_id); + // appears in the where clauses? early-bound. - if appears_in_where_clause.regions.contains(<_name) { + if appears_in_where_clause.regions.contains(¶m_def_id) { continue; } // does not appear in the inputs, but appears in the return type? early-bound. - if !constrained_by_input.regions.contains(<_name) - && appears_in_output.regions.contains(<_name) + if !constrained_by_input.regions.contains(¶m_def_id) + && appears_in_output.regions.contains(¶m_def_id) { continue; } debug!("lifetime {:?} with id {:?} is late-bound", param.name.ident(), param.hir_id); - let inserted = map.late_bound.insert(param.hir_id); + let inserted = late_bound.insert(param_def_id); assert!(inserted, "visited lifetime {:?} twice", param.hir_id); } - return; + debug!(?late_bound); + return Some(tcx.arena.alloc(late_bound)); #[derive(Default)] struct ConstrainedCollector { - regions: FxHashSet<hir::LifetimeName>, + regions: FxHashSet<LocalDefId>, } impl<'v> Visitor<'v> for ConstrainedCollector { @@ -2738,18 +2671,22 @@ fn insert_late_bound_lifetimes( } fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { - self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0()); + if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name { + self.regions.insert(def_id); + } } } #[derive(Default)] struct AllCollector { - regions: FxHashSet<hir::LifetimeName>, + regions: FxHashSet<LocalDefId>, } impl<'v> Visitor<'v> for AllCollector { fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { - self.regions.insert(lifetime_ref.name.normalize_to_macros_2_0()); + if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name { + self.regions.insert(def_id); + } } } } |
