From 39bc74e8b80a08fcf041622f87b0b4b52a1c0ffe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 23 May 2022 17:20:48 +0200 Subject: [PATCH 1/9] Make object_lifetime_defaults a cross-crate query. --- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 60 +++++++------------- 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d8483e7e40914..34639c0b0d0cb 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1579,7 +1579,7 @@ rustc_queries! { /// for each parameter 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(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> { + query object_lifetime_defaults(_: DefId) -> Option<&'tcx [ObjectLifetimeDefault]> { desc { "looking up lifetime defaults for a region on an item" } } query late_bound_vars_map(_: LocalDefId) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 94460e33d8b01..f52db86733b69 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -11,7 +11,7 @@ use rustc_data_structures::fx::{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::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node}; use rustc_middle::bug; @@ -24,7 +24,6 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use std::borrow::Cow; use std::fmt; -use std::mem::take; trait RegionExt { fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region); @@ -131,9 +130,6 @@ pub(crate) struct LifetimeContext<'a, 'tcx> { /// 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, - - /// Cache for cross-crate per-definition object lifetime defaults. - xcrate_object_lifetime_defaults: DefIdMap>, } #[derive(Debug)] @@ -294,9 +290,23 @@ pub fn provide(providers: &mut ty::query::Providers) { named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), is_late_bound_map, - object_lifetime_defaults: |tcx, id| match tcx.hir().find_by_def_id(id) { - Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item), - _ => None, + object_lifetime_defaults: |tcx, def_id| { + if let Some(def_id) = def_id.as_local() { + match tcx.hir().get_by_def_id(def_id) { + Node::Item(item) => compute_object_lifetime_defaults(tcx, item), + _ => None, + } + } else { + Some(tcx.arena.alloc_from_iter(tcx.generics_of(def_id).params.iter().filter_map( + |param| match param.kind { + GenericParamDefKind::Type { object_lifetime_default, .. } => { + Some(object_lifetime_default) + } + GenericParamDefKind::Const { .. } => Some(Set1::Empty), + GenericParamDefKind::Lifetime => None, + }, + ))) + } }, late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id), @@ -363,7 +373,6 @@ fn do_resolve( map: &mut named_region_map, scope: ROOT_SCOPE, trait_definition_only, - xcrate_object_lifetime_defaults: Default::default(), }; visitor.visit_item(item); @@ -1413,20 +1422,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>), { let LifetimeContext { tcx, map, .. } = self; - let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let mut this = LifetimeContext { tcx: *tcx, map, scope: &wrap_scope, trait_definition_only: self.trait_definition_only, - xcrate_object_lifetime_defaults, }; let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope)); { let _enter = span.enter(); f(&mut this); } - self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults; } /// Visits self by adding a scope and handling recursive walk over the contents with `walk`. @@ -1780,35 +1786,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } 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); - self.tcx - .object_lifetime_defaults(id.owner) - .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::Const { .. } => Some(Set1::Empty), - GenericParamDefKind::Lifetime => None, - }) - .collect() - }) - .iter() - .map(set_to_region) - .collect() - } + self.tcx.object_lifetime_defaults(def_id).unwrap().iter().map(set_to_region).collect() }); debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults); From 236ccce79e71020350b8e2d7a263807f02eb6e8e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 24 May 2022 12:51:59 +0200 Subject: [PATCH 2/9] Create a specific `ObjectLifetimeDefault` enum. --- compiler/rustc_middle/src/hir/map/mod.rs | 8 +- .../src/middle/resolve_lifetime.rs | 8 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 112 ++++++------------ compiler/rustc_typeck/src/astconv/mod.rs | 2 - compiler/rustc_typeck/src/collect.rs | 9 +- 6 files changed, 58 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 47b04c33ec1cd..df0687b22249e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -499,7 +499,9 @@ impl<'hir> Map<'hir> { let def_kind = self.tcx.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => def_id, - DefKind::TyParam | DefKind::ConstParam => self.tcx.local_parent(def_id), + DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { + self.tcx.local_parent(def_id) + } _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind), } } @@ -508,7 +510,9 @@ impl<'hir> Map<'hir> { let def_kind = self.tcx.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => kw::SelfUpper, - DefKind::TyParam | DefKind::ConstParam => self.tcx.item_name(def_id.to_def_id()), + DefKind::LifetimeParam | DefKind::TyParam | DefKind::ConstParam => { + self.tcx.item_name(def_id.to_def_id()) + } _ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind), } } diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 9b2f445670532..05f4ab487ef61 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -35,7 +35,13 @@ impl Set1 { } } -pub type ObjectLifetimeDefault = Set1; +#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)] +pub enum ObjectLifetimeDefault { + Empty, + Static, + Ambiguous, + Param(DefId), +} /// Maps the id of each lifetime reference to the lifetime decl /// that it corresponds to. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 34639c0b0d0cb..d8483e7e40914 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1579,7 +1579,7 @@ rustc_queries! { /// for each parameter 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(_: DefId) -> Option<&'tcx [ObjectLifetimeDefault]> { + query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> { desc { "looking up lifetime defaults for a region on an item" } } query late_bound_vars_map(_: LocalDefId) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index f52db86733b69..b96968f81e0a0 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -290,24 +290,7 @@ pub fn provide(providers: &mut ty::query::Providers) { named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), is_late_bound_map, - object_lifetime_defaults: |tcx, def_id| { - if let Some(def_id) = def_id.as_local() { - match tcx.hir().get_by_def_id(def_id) { - Node::Item(item) => compute_object_lifetime_defaults(tcx, item), - _ => None, - } - } else { - Some(tcx.arena.alloc_from_iter(tcx.generics_of(def_id).params.iter().filter_map( - |param| match param.kind { - GenericParamDefKind::Type { object_lifetime_default, .. } => { - Some(object_lifetime_default) - } - GenericParamDefKind::Const { .. } => Some(Set1::Empty), - GenericParamDefKind::Lifetime => None, - }, - ))) - } - }, + object_lifetime_defaults, late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id), ..*providers @@ -1281,10 +1264,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } -fn compute_object_lifetime_defaults<'tcx>( +fn object_lifetime_defaults<'tcx>( tcx: TyCtxt<'tcx>, - item: &hir::Item<'_>, + def_id: LocalDefId, ) -> Option<&'tcx [ObjectLifetimeDefault]> { + let hir::Node::Item(item) = tcx.hir().get_by_def_id(def_id) else { return None; }; match item.kind { hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Union(_, ref generics) @@ -1304,24 +1288,13 @@ fn compute_object_lifetime_defaults<'tcx>( 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 - } - _ => None, - }) - .unwrap(), - Set1::One(_) => bug!(), - Set1::Many => "Ambiguous".into(), + ObjectLifetimeDefault::Empty => "BaseDefault".into(), + ObjectLifetimeDefault::Static => "'static".into(), + ObjectLifetimeDefault::Param(def_id) => { + let def_id = def_id.expect_local(); + tcx.hir().ty_param_name(def_id).to_string().into() + } + ObjectLifetimeDefault::Ambiguous => "Ambiguous".into(), }) .collect::>>() .join(","); @@ -1376,32 +1349,12 @@ fn object_lifetime_defaults_for_item<'tcx>( } Some(match set { - Set1::Empty => Set1::Empty, - Set1::One(name) => { - if name == hir::LifetimeName::Static { - Set1::One(Region::Static) - } else { - generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - 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, (def_id, _))| { - Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id())) - }) - } + Set1::Empty => ObjectLifetimeDefault::Empty, + Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static, + Set1::One(hir::LifetimeName::Param(param_def_id, _)) => { + ObjectLifetimeDefault::Param(param_def_id.to_def_id()) } - Set1::Many => Set1::Many, + _ => ObjectLifetimeDefault::Ambiguous, }) } GenericParamKind::Const { .. } => { @@ -1409,7 +1362,7 @@ fn object_lifetime_defaults_for_item<'tcx>( // // We still store a dummy value here to allow generic parameters // in an arbitrary order. - Some(Set1::Empty) + Some(ObjectLifetimeDefault::Empty) } }; @@ -1769,24 +1722,37 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }; let map = &self.map; - let set_to_region = |set: &ObjectLifetimeDefault| match *set { - Set1::Empty => { + let generics = self.tcx.generics_of(def_id); + let set_to_region = |set: ObjectLifetimeDefault| match set { + ObjectLifetimeDefault::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), + ObjectLifetimeDefault::Static => Some(Region::Static), + ObjectLifetimeDefault::Param(param_def_id) => { + let index = generics.param_def_id_to_index[¶m_def_id]; + generic_args.args.get(index as usize).and_then(|arg| match arg { + GenericArg::Lifetime(lt) => map.defs.get(<.hir_id).copied(), _ => None, - }); - r.subst(lifetimes, map) + }) } - Set1::Many => None, + ObjectLifetimeDefault::Ambiguous => None, }; - self.tcx.object_lifetime_defaults(def_id).unwrap().iter().map(set_to_region).collect() + generics + .params + .iter() + .filter_map(|param| match param.kind { + GenericParamDefKind::Type { object_lifetime_default, .. } => { + Some(object_lifetime_default) + } + GenericParamDefKind::Const { .. } => Some(ObjectLifetimeDefault::Empty), + GenericParamDefKind::Lifetime => None, + }) + .map(set_to_region) + .collect() }); debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 8a5c7fee697d1..ee184a093918e 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -252,9 +252,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }) } }; - debug!("ast_region_to_region(lifetime={:?}) yields {:?}", lifetime, r); - r } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 99996e80c9ce9..1c1df4a2f7f9f 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -34,6 +34,7 @@ use rustc_hir::weak_lang_items; use rustc_hir::{GenericParamKind, HirId, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; +use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; @@ -1597,7 +1598,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: rl::Set1::Empty, + object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, }); @@ -1671,7 +1672,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { has_default: default.is_some(), object_lifetime_default: object_lifetime_defaults .as_ref() - .map_or(rl::Set1::Empty, |o| o[i]), + .map_or(ObjectLifetimeDefault::Empty, |o| o[i]), synthetic, }; @@ -1727,7 +1728,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: rl::Set1::Empty, + object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, })); @@ -1744,7 +1745,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: rl::Set1::Empty, + object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, }); From 99e2d33315afa0168e971d929667dde0158200e7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 May 2022 20:15:34 +0200 Subject: [PATCH 3/9] Compute `object_lifetime_default` per parameter. --- .../src/rmeta/decoder/cstore_impl.rs | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 5 + compiler/rustc_metadata/src/rmeta/mod.rs | 2 + compiler/rustc_middle/src/query/mod.rs | 5 +- compiler/rustc_middle/src/ty/generics.rs | 3 +- compiler/rustc_middle/src/ty/parameterized.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 28 +++++ compiler/rustc_resolve/src/late/lifetimes.rs | 108 ++++-------------- compiler/rustc_typeck/src/collect.rs | 24 +--- 9 files changed, 68 insertions(+), 109 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 38ce50e8323b1..14a28cf7d3f89 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -199,6 +199,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, codegen_fn_attrs => { table } impl_trait_ref => { table } const_param_default => { table } + object_lifetime_default => { table } thir_abstract_const => { table } optimized_mir => { table } mir_for_ctfe => { table } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 33278367ce32d..50a309f8785cb 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1044,6 +1044,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives); } } + if let DefKind::TyParam | DefKind::ConstParam = def_kind { + if let Some(default) = self.tcx.object_lifetime_default(def_id) { + record!(self.tables.object_lifetime_default[def_id] <- default); + } + } if let DefKind::Trait | DefKind::TraitAlias = def_kind { record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id)); } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 66bdecc30db85..2f3493d1b19d1 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -16,6 +16,7 @@ use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; +use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc_middle::mir; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::query::Providers; @@ -357,6 +358,7 @@ define_tables! { codegen_fn_attrs: Table>, impl_trait_ref: Table>>, const_param_default: Table>>, + object_lifetime_default: Table>, optimized_mir: Table>>, mir_for_ctfe: Table>>, promoted_mir: Table>>>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index d8483e7e40914..ff296116a1ff6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1579,8 +1579,9 @@ rustc_queries! { /// for each parameter 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(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> { - desc { "looking up lifetime defaults for a region on an item" } + query object_lifetime_default(key: DefId) -> Option { + desc { "looking up lifetime defaults for generic parameter `{:?}`", key } + separate_provide_extern } query late_bound_vars_map(_: LocalDefId) -> Option<&'tcx FxHashMap>> { diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index add2df25884e3..d6a55af51e523 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -1,4 +1,3 @@ -use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::ty; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::EarlyBinder; @@ -13,7 +12,7 @@ use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predi #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub enum GenericParamDefKind { Lifetime, - Type { has_default: bool, object_lifetime_default: ObjectLifetimeDefault, synthetic: bool }, + Type { has_default: bool, synthetic: bool }, Const { has_default: bool }, } diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index e189ee2fc4db1..067ad927a0358 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -53,6 +53,7 @@ trivially_parameterized_over_tcx! { crate::metadata::ModChild, crate::middle::codegen_fn_attrs::CodegenFnAttrs, crate::middle::exported_symbols::SymbolExportInfo, + crate::middle::resolve_lifetime::ObjectLifetimeDefault, crate::mir::ConstQualifs, ty::Generics, ty::ImplPolarity, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index fde12b9eee6b9..33ab2e12eddca 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -16,6 +16,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID}; use rustc_hir::{MethodKind, Target}; use rustc_middle::hir::nested_filter; +use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ @@ -171,6 +172,9 @@ impl CheckAttrVisitor<'_> { sym::no_implicit_prelude => { self.check_generic_attr(hir_id, attr, target, &[Target::Mod]) } + sym::rustc_object_lifetime_default => { + self.check_object_lifetime_default(hir_id, span) + } _ => {} } @@ -402,6 +406,30 @@ impl CheckAttrVisitor<'_> { } } + /// Debugging aid for `object_lifetime_default` query. + fn check_object_lifetime_default(&self, hir_id: HirId, span: Span) { + let tcx = self.tcx; + if let Some(generics) = tcx.hir().get_generics(tcx.hir().local_def_id(hir_id)) { + let object_lifetime_default_reprs: String = generics + .params + .iter() + .filter_map(|p| { + let param_id = tcx.hir().local_def_id(p.hir_id); + let default = tcx.object_lifetime_default(param_id)?; + Some(match default { + ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(), + ObjectLifetimeDefault::Static => "'static".to_owned(), + ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(), + ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(), + }) + }) + .collect::>() + .join(","); + + tcx.sess.span_err(span, &object_lifetime_default_reprs); + } + } + /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid. fn check_track_caller( &self, diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index b96968f81e0a0..52980f15971cc 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -18,11 +18,10 @@ use rustc_middle::bug; use rustc_middle::hir::map::Map; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_lifetime::*; -use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; -use std::borrow::Cow; use std::fmt; trait RegionExt { @@ -290,7 +289,7 @@ pub fn provide(providers: &mut ty::query::Providers) { named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), is_late_bound_map, - object_lifetime_defaults, + object_lifetime_default, late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id), ..*providers @@ -1264,87 +1263,36 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } -fn object_lifetime_defaults<'tcx>( +fn object_lifetime_default<'tcx>( tcx: TyCtxt<'tcx>, - def_id: LocalDefId, -) -> Option<&'tcx [ObjectLifetimeDefault]> { - let hir::Node::Item(item) = tcx.hir().get_by_def_id(def_id) else { return None; }; - 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, - origin: hir::OpaqueTyOrigin::TyAlias, - .. - }) - | 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 { - ObjectLifetimeDefault::Empty => "BaseDefault".into(), - ObjectLifetimeDefault::Static => "'static".into(), - ObjectLifetimeDefault::Param(def_id) => { - let def_id = def_id.expect_local(); - tcx.hir().ty_param_name(def_id).to_string().into() - } - ObjectLifetimeDefault::Ambiguous => "Ambiguous".into(), - }) - .collect::>>() - .join(","); - tcx.sess.span_err(item.span, &object_lifetime_default_reprs); - } - - Some(result) - } - _ => None, - } -} - -/// Scan the bounds and where-clauses on parameters to extract bounds -/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault` -/// for each type parameter. -fn object_lifetime_defaults_for_item<'tcx>( - tcx: TyCtxt<'tcx>, - generics: &hir::Generics<'_>, -) -> &'tcx [ObjectLifetimeDefault] { - fn add_bounds(set: &mut Set1, bounds: &[hir::GenericBound<'_>]) { - for bound in bounds { - if let hir::GenericBound::Outlives(ref lifetime) = *bound { - set.insert(lifetime.name.normalize_to_macros_2_0()); - } - } - } - - let process_param = |param: &hir::GenericParam<'_>| match param.kind { + param_def_id: DefId, +) -> Option { + let param_def_id = param_def_id.expect_local(); + let parent_def_id = tcx.local_parent(param_def_id); + let generics = tcx.hir().get_generics(parent_def_id)?; + let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id); + let param = generics.params.iter().find(|p| p.hir_id == param_hir_id)?; + + // Scan the bounds and where-clauses on parameters to extract bounds + // of the form `T:'a` so as to determine the `ObjectLifetimeDefault` + // for each type parameter. + match param.kind { GenericParamKind::Lifetime { .. } => None, GenericParamKind::Type { .. } => { let mut set = Set1::Empty; - let param_def_id = tcx.hir().local_def_id(param.hir_id); - for predicate in generics.predicates { - // Look for `type: ...` where clauses. - let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue }; - + // Look for `type: ...` where clauses. + for bound in generics.bounds_for_param(param_def_id) { // Ignore `for<'a> type: ...` as they can change what // lifetimes mean (although we could "just" handle it). - if !data.bound_generic_params.is_empty() { + if !bound.bound_generic_params.is_empty() { continue; } - let res = match data.bounded_ty.kind { - hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res, - _ => continue, - }; - - if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) { - add_bounds(&mut set, &data.bounds); + for bound in bound.bounds { + if let hir::GenericBound::Outlives(ref lifetime) = *bound { + set.insert(lifetime.name.normalize_to_macros_2_0()); + } } } @@ -1364,9 +1312,7 @@ fn object_lifetime_defaults_for_item<'tcx>( // in an arbitrary order. Some(ObjectLifetimeDefault::Empty) } - }; - - tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param)) + } } impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { @@ -1744,13 +1690,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { generics .params .iter() - .filter_map(|param| match param.kind { - GenericParamDefKind::Type { object_lifetime_default, .. } => { - Some(object_lifetime_default) - } - GenericParamDefKind::Const { .. } => Some(ObjectLifetimeDefault::Empty), - GenericParamDefKind::Lifetime => None, - }) + .filter_map(|param| self.tcx.object_lifetime_default(param.def_id)) .map(set_to_region) .collect() }); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 1c1df4a2f7f9f..0ec2acafd07ff 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -34,7 +34,6 @@ use rustc_hir::weak_lang_items; use rustc_hir::{GenericParamKind, HirId, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; -use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault; use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; @@ -1598,7 +1597,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { has_default: false, - object_lifetime_default: ObjectLifetimeDefault::Empty, synthetic: false, }, }); @@ -1642,8 +1640,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { kind: ty::GenericParamDefKind::Lifetime, })); - let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner); - // Now create the real type and const parameters. let type_start = own_start - has_self as u32 + params.len() as u32; let mut i = 0; @@ -1668,13 +1664,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { } } - let kind = ty::GenericParamDefKind::Type { - has_default: default.is_some(), - object_lifetime_default: object_lifetime_defaults - .as_ref() - .map_or(ObjectLifetimeDefault::Empty, |o| o[i]), - synthetic, - }; + let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic }; let param_def = ty::GenericParamDef { index: type_start + i as u32, @@ -1726,11 +1716,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { name: Symbol::intern(arg), def_id, pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { - has_default: false, - object_lifetime_default: ObjectLifetimeDefault::Empty, - synthetic: false, - }, + kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, })); } @@ -1743,11 +1729,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { name: Symbol::intern(""), def_id, pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { - has_default: false, - object_lifetime_default: ObjectLifetimeDefault::Empty, - synthetic: false, - }, + kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, }); } } From 63c3aabeb8fdde119384562341b2d3b201be54ed Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 24 May 2022 08:31:11 +0200 Subject: [PATCH 4/9] Create lifetime parameter like any other parameter. --- compiler/rustc_typeck/src/astconv/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index ee184a093918e..dd6831e44fdc1 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -221,9 +221,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.mk_region(ty::ReLateBound(debruijn, br)) } - Some(rl::Region::EarlyBound(index, id)) => { - let name = lifetime_name(id.expect_local()); - tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: id, index, name })) + Some(rl::Region::EarlyBound(_, def_id)) => { + let name = tcx.hir().ty_param_name(def_id.expect_local()); + let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local()); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&def_id]; + tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name })) } Some(rl::Region::Free(scope, id)) => { From 421bb6ac62f5624a05d9e4ff0a12c91da91e49a8 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 24 May 2022 13:00:36 +0200 Subject: [PATCH 5/9] Remove index from Region::EarlyBound. --- .../nice_region_error/find_anon_type.rs | 8 +- compiler/rustc_lint/src/builtin.rs | 19 +- .../src/middle/resolve_lifetime.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 223 ++---------------- compiler/rustc_typeck/src/astconv/mod.rs | 10 +- src/librustdoc/clean/mod.rs | 2 +- 6 files changed, 50 insertions(+), 214 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs index c1b201da69121..ddad72fdab93d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs @@ -103,7 +103,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { // Find the index of the named region that was part of the // error. We will then search the function parameters for a bound // region at the right depth with the same index - (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { + (Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { self.found_type = Some(arg); @@ -133,7 +133,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> { Some( rl::Region::Static | rl::Region::Free(_, _) - | rl::Region::EarlyBound(_, _) + | rl::Region::EarlyBound(_) | rl::Region::LateBound(_, _, _), ) | None, @@ -188,7 +188,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { fn visit_lifetime(&mut self, lifetime: &hir::Lifetime) { match (self.tcx.named_region(lifetime.hir_id), self.bound_region) { // the lifetime of the TyPath! - (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { + (Some(rl::Region::EarlyBound(id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound id={:?} def_id={:?}", id, def_id); if id == def_id { self.found_it = true; @@ -209,7 +209,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> { ( Some( rl::Region::Static - | rl::Region::EarlyBound(_, _) + | rl::Region::EarlyBound(_) | rl::Region::LateBound(_, _, _) | rl::Region::Free(_, _), ) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index bd58021f78fc0..7c49749137db5 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2039,13 +2039,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN impl ExplicitOutlivesRequirements { fn lifetimes_outliving_lifetime<'tcx>( inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], - index: u32, + def_id: DefId, ) -> Vec> { inferred_outlives .iter() .filter_map(|(pred, _)| match pred.kind().skip_binder() { ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { - ty::ReEarlyBound(ebr) if ebr.index == index => Some(b), + ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b), _ => None, }, _ => None, @@ -2082,8 +2082,12 @@ impl ExplicitOutlivesRequirements { .filter_map(|(i, bound)| { if let hir::GenericBound::Outlives(lifetime) = bound { let is_inferred = match tcx.named_region(lifetime.hir_id) { - Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| { - if let ty::ReEarlyBound(ebr) = **r { ebr.index == index } else { false } + Some(Region::EarlyBound(def_id)) => inferred_outlives.iter().any(|r| { + if let ty::ReEarlyBound(ebr) = **r { + ebr.def_id == def_id + } else { + false + } }), _ => false, }; @@ -2177,11 +2181,14 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { for (i, where_predicate) in hir_generics.predicates.iter().enumerate() { let (relevant_lifetimes, bounds, span, in_where_clause) = match where_predicate { hir::WherePredicate::RegionPredicate(predicate) => { - if let Some(Region::EarlyBound(index, ..)) = + if let Some(Region::EarlyBound(region_def_id)) = cx.tcx.named_region(predicate.lifetime.hir_id) { ( - Self::lifetimes_outliving_lifetime(inferred_outlives, index), + Self::lifetimes_outliving_lifetime( + inferred_outlives, + region_def_id, + ), &predicate.bounds, predicate.span, predicate.in_where_clause, diff --git a/compiler/rustc_middle/src/middle/resolve_lifetime.rs b/compiler/rustc_middle/src/middle/resolve_lifetime.rs index 05f4ab487ef61..a171f5711dcff 100644 --- a/compiler/rustc_middle/src/middle/resolve_lifetime.rs +++ b/compiler/rustc_middle/src/middle/resolve_lifetime.rs @@ -10,7 +10,7 @@ use rustc_macros::HashStable; #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, HashStable)] pub enum Region { Static, - EarlyBound(/* index */ u32, /* lifetime decl */ DefId), + EarlyBound(/* lifetime decl */ DefId), LateBound(ty::DebruijnIndex, /* late-bound index */ u32, /* lifetime decl */ DefId), Free(DefId, /* lifetime decl */ DefId), } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 52980f15971cc..01ada080b019c 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -25,7 +25,7 @@ use rustc_span::Span; use std::fmt; trait RegionExt { - fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region); + fn early(hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region); fn late(index: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region); @@ -34,19 +34,13 @@ trait RegionExt { fn shifted(self, amount: u32) -> Region; fn shifted_out_to_binder(self, binder: ty::DebruijnIndex) -> Region; - - fn subst<'a, L>(self, params: L, map: &NamedRegionMap) -> Option - where - L: Iterator; } impl RegionExt for Region { - fn early(hir_map: Map<'_>, index: &mut u32, param: &GenericParam<'_>) -> (LocalDefId, Region) { - let i = *index; - *index += 1; + fn early(hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) { let def_id = hir_map.local_def_id(param.hir_id); - debug!("Region::early: index={} def_id={:?}", i, def_id); - (def_id, Region::EarlyBound(i, def_id.to_def_id())) + debug!("Region::early: def_id={:?}", def_id); + (def_id, Region::EarlyBound(def_id.to_def_id())) } fn late(idx: u32, hir_map: Map<'_>, param: &GenericParam<'_>) -> (LocalDefId, Region) { @@ -63,9 +57,7 @@ impl RegionExt for Region { match *self { Region::Static => None, - Region::EarlyBound(_, id) | Region::LateBound(_, _, id) | Region::Free(_, id) => { - Some(id) - } + Region::EarlyBound(id) | Region::LateBound(_, _, id) | Region::Free(_, id) => Some(id), } } @@ -86,17 +78,6 @@ impl RegionExt for Region { _ => self, } } - - fn subst<'a, L>(self, mut params: L, map: &NamedRegionMap) -> Option - where - L: Iterator, - { - if let Region::EarlyBound(index, _) = self { - params.nth(index as usize).and_then(|lifetime| map.defs.get(&lifetime.hir_id).cloned()) - } else { - Some(self) - } - } } /// Maps the id of each lifetime reference to the lifetime decl @@ -142,25 +123,6 @@ enum Scope<'a> { /// for diagnostics. lifetimes: FxIndexMap, - /// if we extend this scope with another scope, what is the next index - /// we should use for an early-bound region? - next_early_index: u32, - - /// Whether or not this binder would serve as the parent - /// binder for opaque types introduced within. For example: - /// - /// ```text - /// fn foo<'a>() -> impl for<'b> Trait> - /// ``` - /// - /// Here, the opaque types we create for the `impl Trait` - /// and `impl Trait2` references will both have the `foo` item - /// as their parent. When we get to `impl Trait2`, we find - /// that it is nested within the `for<>` binder -- this flag - /// allows us to skip that when looking for the parent binder - /// of the resulting opaque type. - opaque_type_parent: bool, - scope_type: BinderScopeType, /// The late bound vars for a given item are stored by `HirId` to be @@ -240,19 +202,9 @@ 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, - opaque_type_parent, - scope_type, - hir_id, - where_bound_origin, - s: _, - } => f + Scope::Binder { lifetimes, scope_type, hir_id, where_bound_origin, s: _ } => f .debug_struct("Binder") .field("lifetimes", lifetimes) - .field("next_early_index", next_early_index) - .field("opaque_type_parent", opaque_type_parent) .field("scope_type", scope_type) .field("hir_id", hir_id) .field("where_bound_origin", where_bound_origin) @@ -423,13 +375,6 @@ fn item_for(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> LocalDefId { item } -/// 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. -fn sub_items_have_self_param(node: &hir::ItemKind<'_>) -> bool { - matches!(*node, hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..)) -} - fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::BoundVariableKind { match region { Region::LateBound(_, _, def_id) => { @@ -549,7 +494,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } - let next_early_index = self.next_early_index(); let (lifetimes, binders): (FxIndexMap, Vec<_>) = bound_generic_params .iter() @@ -567,8 +511,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir_id: e.hir_id, lifetimes, s: self.scope, - next_early_index, - opaque_type_parent: false, scope_type: BinderScopeType::Normal, where_bound_origin: None, }; @@ -594,7 +536,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } match item.kind { hir::ItemKind::Fn(_, ref generics, _) => { - self.visit_early_late(None, item.hir_id(), generics, |this| { + self.visit_early_late(item.hir_id(), generics, |this| { intravisit::walk_item(this, item); }); } @@ -661,31 +603,20 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::TraitAlias(ref generics, ..) | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => { // These kinds of items have only early-bound lifetime parameters. - let mut index = if sub_items_have_self_param(&item.kind) { - 1 // Self comes before lifetimes - } else { - 0 - }; - let mut non_lifetime_count = 0; let lifetimes = generics .params .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::early(self.tcx.hir(), &mut index, param)) - } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - non_lifetime_count += 1; - None + Some(Region::early(self.tcx.hir(), param)) } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, }) .collect(); self.map.late_bound_vars.insert(item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: item.hir_id(), lifetimes, - next_early_index: index + non_lifetime_count, - opaque_type_parent: true, scope_type: BinderScopeType::Normal, s: ROOT_SCOPE, where_bound_origin: None, @@ -703,7 +634,7 @@ 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 generics) => { - self.visit_early_late(None, item.hir_id(), generics, |this| { + self.visit_early_late(item.hir_id(), generics, |this| { intravisit::walk_foreign_item(this, item); }) } @@ -720,7 +651,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { match ty.kind { hir::TyKind::BareFn(ref c) => { - let next_early_index = self.next_early_index(); let (lifetimes, binders): (FxIndexMap, Vec<_>) = c .generic_params .iter() @@ -737,8 +667,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir_id: ty.hir_id, lifetimes, s: self.scope, - next_early_index, - opaque_type_parent: false, scope_type: BinderScopeType::Normal, where_bound_origin: None, }; @@ -877,32 +805,23 @@ 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!(?index); - let mut lifetimes = FxIndexMap::default(); - let mut non_lifetime_count = 0; debug!(?generics.params); for param in generics.params { match param.kind { GenericParamKind::Lifetime { .. } => { - let (def_id, reg) = Region::early(self.tcx.hir(), &mut index, ¶m); + let (def_id, reg) = Region::early(self.tcx.hir(), ¶m); lifetimes.insert(def_id, reg); } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - non_lifetime_count += 1; - } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {} } } - let next_early_index = index + non_lifetime_count; self.map.late_bound_vars.insert(ty.hir_id, vec![]); let scope = Scope::Binder { hir_id: ty.hir_id, lifetimes, - next_early_index, s: self.scope, - opaque_type_parent: false, scope_type: BinderScopeType::Normal, where_bound_origin: None, }; @@ -924,39 +843,27 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { use self::hir::TraitItemKind::*; match trait_item.kind { Fn(_, _) => { - let tcx = self.tcx; - self.visit_early_late( - Some(tcx.hir().get_parent_item(trait_item.hir_id())), - trait_item.hir_id(), - &trait_item.generics, - |this| intravisit::walk_trait_item(this, trait_item), - ); + self.visit_early_late(trait_item.hir_id(), &trait_item.generics, |this| { + intravisit::walk_trait_item(this, trait_item) + }); } Type(bounds, ref ty) => { let generics = &trait_item.generics; - let mut index = self.next_early_index(); - debug!("visit_ty: index = {}", index); - let mut non_lifetime_count = 0; let lifetimes = generics .params .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::early(self.tcx.hir(), &mut index, param)) - } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - non_lifetime_count += 1; - None + Some(Region::early(self.tcx.hir(), param)) } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, }) .collect(); self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: trait_item.hir_id(), lifetimes, - next_early_index: index + non_lifetime_count, s: self.scope, - opaque_type_parent: true, scope_type: BinderScopeType::Normal, where_bound_origin: None, }; @@ -984,40 +891,26 @@ 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(..) => { - let tcx = self.tcx; - self.visit_early_late( - Some(tcx.hir().get_parent_item(impl_item.hir_id())), - impl_item.hir_id(), - &impl_item.generics, - |this| intravisit::walk_impl_item(this, impl_item), - ); - } + Fn(..) => self.visit_early_late(impl_item.hir_id(), &impl_item.generics, |this| { + intravisit::walk_impl_item(this, impl_item) + }), TyAlias(ref ty) => { let generics = &impl_item.generics; - let mut index = self.next_early_index(); - let mut non_lifetime_count = 0; - debug!("visit_ty: index = {}", index); let lifetimes: FxIndexMap = generics .params .iter() .filter_map(|param| match param.kind { GenericParamKind::Lifetime { .. } => { - Some(Region::early(self.tcx.hir(), &mut index, param)) - } - GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => { - non_lifetime_count += 1; - None + Some(Region::early(self.tcx.hir(), param)) } + GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None, }) .collect(); self.map.late_bound_vars.insert(ty.hir_id, vec![]); let scope = Scope::Binder { hir_id: ty.hir_id, lifetimes, - next_early_index: index + non_lifetime_count, s: self.scope, - opaque_type_parent: true, scope_type: BinderScopeType::Normal, where_bound_origin: None, }; @@ -1120,7 +1013,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }) .unzip(); this.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone()); - let next_early_index = this.next_early_index(); // Even if there are no lifetimes defined here, we still wrap it in a binder // scope. If there happens to be a nested poly trait ref (an error), that // will be `Concatenating` anyways, so we don't have to worry about the depth @@ -1129,8 +1021,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir_id: bounded_ty.hir_id, lifetimes, s: this.scope, - next_early_index, - opaque_type_parent: false, scope_type: BinderScopeType::Normal, where_bound_origin: Some(origin), }; @@ -1201,8 +1091,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir_id: *hir_id, lifetimes: FxIndexMap::default(), s: self.scope, - next_early_index: self.next_early_index(), - opaque_type_parent: false, scope_type, where_bound_origin: None, }; @@ -1221,7 +1109,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { ) { debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref); - let next_early_index = self.next_early_index(); let (mut binders, scope_type) = self.poly_trait_ref_binder_info(); let initial_bound_vars = binders.len() as u32; @@ -1251,8 +1138,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir_id: trait_ref.trait_ref.hir_ref_id, lifetimes, s: self.scope, - next_early_index, - opaque_type_parent: false, scope_type, where_bound_origin: None, }; @@ -1354,30 +1239,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { /// ordering is not important there. fn visit_early_late( &mut self, - parent_id: Option, hir_id: hir::HirId, generics: &'tcx hir::Generics<'tcx>, walk: F, ) where F: for<'b, 'c> FnOnce(&'b mut LifetimeContext<'c, 'tcx>), { - // Find the start of nested early scopes, e.g., in methods. - let mut next_early_index = 0; - if let Some(parent_id) = parent_id { - let parent = self.tcx.hir().expect_item(parent_id); - if sub_items_have_self_param(&parent.kind) { - next_early_index += 1; // Self comes before lifetimes - } - match parent.kind { - hir::ItemKind::Trait(_, _, ref generics, ..) - | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => { - next_early_index += generics.params.len() as u32; - } - _ => {} - } - } - - let mut non_lifetime_count = 0; let mut named_late_bound_vars = 0; let lifetimes: FxIndexMap = generics .params @@ -1389,16 +1256,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { named_late_bound_vars += 1; Some(Region::late(late_bound_idx, self.tcx.hir(), param)) } else { - Some(Region::early(self.tcx.hir(), &mut next_early_index, param)) + Some(Region::early(self.tcx.hir(), param)) } } - GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - non_lifetime_count += 1; - None - } + GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, }) .collect(); - let next_early_index = next_early_index + non_lifetime_count; let binders: Vec<_> = generics .params @@ -1417,51 +1280,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let scope = Scope::Binder { hir_id, lifetimes, - next_early_index, s: self.scope, - opaque_type_parent: true, scope_type: BinderScopeType::Normal, where_bound_origin: None, }; self.with(scope, walk); } - fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 { - let mut scope = self.scope; - loop { - match *scope { - Scope::Root => return 0, - - Scope::Binder { next_early_index, opaque_type_parent, .. } - if (!only_opaque_type_parent || opaque_type_parent) => - { - return next_early_index; - } - - Scope::Binder { s, .. } - | Scope::Body { s, .. } - | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } - | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } => scope = s, - } - } - } - - /// Returns the next index one would use for an early-bound-region - /// if extending the current scope. - fn next_early_index(&self) -> u32 { - self.next_early_index_helper(true) - } - - /// Returns the next index one would use for an `impl Trait` that - /// is being converted into an opaque type alias `impl Trait`. This will be the - /// next early index from the enclosing item, for the most - /// part. See the `opaque_type_parent` field for more info. - fn next_early_index_for_opaque_type(&self) -> u32 { - self.next_early_index_helper(false) - } - #[tracing::instrument(level = "debug", skip(self))] fn resolve_lifetime_ref( &mut self, diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index dd6831e44fdc1..bb2c533aa16ec 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -221,7 +221,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.mk_region(ty::ReLateBound(debruijn, br)) } - Some(rl::Region::EarlyBound(_, def_id)) => { + Some(rl::Region::EarlyBound(def_id)) => { let name = tcx.hir().ty_param_name(def_id.expect_local()); let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local()); let generics = tcx.generics_of(item_def_id); @@ -2840,10 +2840,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ); if !infer_replacements.is_empty() { - diag.multipart_suggestion(&format!( + diag.multipart_suggestion( + &format!( "try replacing `_` with the type{} in the corresponding trait method signature", rustc_errors::pluralize!(infer_replacements.len()), - ), infer_replacements, Applicability::MachineApplicable); + ), + infer_replacements, + Applicability::MachineApplicable, + ); } diag.emit(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 116b1f16f7f4b..d8955a50cd2ab 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -216,7 +216,7 @@ impl<'tcx> Clean<'tcx, GenericBound> for ty::PolyTraitRef<'tcx> { fn clean_lifetime<'tcx>(lifetime: hir::Lifetime, cx: &mut DocContext<'tcx>) -> Lifetime { let def = cx.tcx.named_region(lifetime.hir_id); if let Some( - rl::Region::EarlyBound(_, node_id) + rl::Region::EarlyBound(node_id) | rl::Region::LateBound(_, _, node_id) | rl::Region::Free(_, node_id), ) = def From 48bae9360feea931a0ef635ef1b69c61113dcd1a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Jul 2022 22:06:30 +0200 Subject: [PATCH 6/9] Use DefIdTree instead of open-coding it. --- compiler/rustc_resolve/src/late/lifetimes.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 01ada080b019c..1892216dec002 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1437,13 +1437,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { // Figure out if this is a type/trait segment, // which requires object lifetime defaults. - let parent_def_id = |this: &mut Self, def_id: DefId| { - let def_key = this.tcx.def_key(def_id); - DefId { krate: def_id.krate, index: def_key.parent.expect("missing parent") } - }; let type_def_id = match res { - Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(parent_def_id(self, def_id)), - Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(parent_def_id(self, def_id)), + Res::Def(DefKind::AssocTy, def_id) if depth == 1 => Some(self.tcx.parent(def_id)), + Res::Def(DefKind::Variant, def_id) if depth == 0 => Some(self.tcx.parent(def_id)), Res::Def( DefKind::Struct | DefKind::Union From a4240902529b75ed39995f506331eb532a6a0c51 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Jul 2022 22:06:41 +0200 Subject: [PATCH 7/9] Simplify debugging. --- compiler/rustc_resolve/src/late/lifetimes.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 1892216dec002..4c894ccd53d99 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1409,17 +1409,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { ); } + #[tracing::instrument(level = "debug", skip(self))] fn visit_segment_args( &mut self, res: Res, depth: usize, generic_args: &'tcx hir::GenericArgs<'tcx>, ) { - debug!( - "visit_segment_args(res={:?}, depth={:?}, generic_args={:?})", - res, depth, generic_args, - ); - if generic_args.parenthesized { self.visit_fn_like_elision( generic_args.inputs(), @@ -1451,7 +1447,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { _ => None, }; - debug!("visit_segment_args: type_def_id={:?}", type_def_id); + debug!(?type_def_id); // Compute a vector of defaults, one for each type parameter, // per the rules given in RFCs 599 and 1156. Example: @@ -1516,7 +1512,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .collect() }); - debug!("visit_segment_args: object_lifetime_defaults={:?}", object_lifetime_defaults); + debug!(?object_lifetime_defaults); let mut i = 0; for arg in generic_args.args { From c95ff1d52bd3d8abec2e39b5b76426e22cc6d582 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Jul 2022 22:22:39 +0200 Subject: [PATCH 8/9] Assert index sanity. --- compiler/rustc_resolve/src/late/lifetimes.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 4c894ccd53d99..6ea976a590064 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1486,6 +1486,10 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let map = &self.map; let generics = self.tcx.generics_of(def_id); + + // `type_def_id` points to an item, so there is nothing to inherit generics from. + debug_assert_eq!(generics.parent_count, 0); + let set_to_region = |set: ObjectLifetimeDefault| match set { ObjectLifetimeDefault::Empty => { if in_body { @@ -1496,8 +1500,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } ObjectLifetimeDefault::Static => Some(Region::Static), ObjectLifetimeDefault::Param(param_def_id) => { - let index = generics.param_def_id_to_index[¶m_def_id]; - generic_args.args.get(index as usize).and_then(|arg| match arg { + // This index can be used with `generic_args` since `parent_count == 0`. + let index = generics.param_def_id_to_index[¶m_def_id] as usize; + generic_args.args.get(index).and_then(|arg| match arg { GenericArg::Lifetime(lt) => map.defs.get(<.hir_id).copied(), _ => None, }) From da90ec17e01d8360650a096ec53db5470839b3ab Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 27 Jul 2022 23:34:57 +0200 Subject: [PATCH 9/9] Bless incremental tests. --- src/test/incremental/hashes/enum_defs.rs | 8 ++++---- src/test/incremental/hashes/trait_defs.rs | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs index b466cfdd59594..0f8898c389b7f 100644 --- a/src/test/incremental/hashes/enum_defs.rs +++ b/src/test/incremental/hashes/enum_defs.rs @@ -504,9 +504,9 @@ enum EnumAddLifetimeBoundToParameter<'a, T> { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")] +#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")] +#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail6")] enum EnumAddLifetimeBoundToParameter<'a, T: 'a> { Variant1(T), @@ -559,9 +559,9 @@ enum EnumAddLifetimeBoundToParameterWhere<'a, T> { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")] +#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,generics_of,predicates_of")] +#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,predicates_of")] #[rustc_clean(cfg="cfail6")] enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a { Variant1(T), diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 1988f3f35417c..c453eeceb77f5 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -1066,9 +1066,9 @@ trait TraitAddTraitBoundToTypeParameterOfTrait { } trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T> { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T: 'a> { } @@ -1144,9 +1144,9 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTrait { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a + 'b> { } @@ -1201,9 +1201,9 @@ trait TraitAddTraitBoundToTypeParameterOfTraitWhere where T: ReferencedTrait0 trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> where T: 'a { } @@ -1254,9 +1254,9 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail2")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes,generics_of,predicates_of", cfg="cfail5")] +#[rustc_clean(except="hir_owner,hir_owner_nodes,predicates_of", cfg="cfail5")] #[rustc_clean(cfg="cfail6")] trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a + 'b { }