Skip to content

Commit 99e2d33

Browse files
committed
Compute object_lifetime_default per parameter.
1 parent 236ccce commit 99e2d33

File tree

9 files changed

+68
-109
lines changed

9 files changed

+68
-109
lines changed

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
199199
codegen_fn_attrs => { table }
200200
impl_trait_ref => { table }
201201
const_param_default => { table }
202+
object_lifetime_default => { table }
202203
thir_abstract_const => { table }
203204
optimized_mir => { table }
204205
mir_for_ctfe => { table }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
10441044
record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
10451045
}
10461046
}
1047+
if let DefKind::TyParam | DefKind::ConstParam = def_kind {
1048+
if let Some(default) = self.tcx.object_lifetime_default(def_id) {
1049+
record!(self.tables.object_lifetime_default[def_id] <- default);
1050+
}
1051+
}
10471052
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
10481053
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
10491054
}

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
1616
use rustc_middle::metadata::ModChild;
1717
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
1818
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
19+
use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
1920
use rustc_middle::mir;
2021
use rustc_middle::ty::fast_reject::SimplifiedType;
2122
use rustc_middle::ty::query::Providers;
@@ -357,6 +358,7 @@ define_tables! {
357358
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
358359
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
359360
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
361+
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
360362
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
361363
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
362364
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,8 +1579,9 @@ rustc_queries! {
15791579
/// for each parameter if a trait object were to be passed for that parameter.
15801580
/// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
15811581
/// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
1582-
query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
1583-
desc { "looking up lifetime defaults for a region on an item" }
1582+
query object_lifetime_default(key: DefId) -> Option<ObjectLifetimeDefault> {
1583+
desc { "looking up lifetime defaults for generic parameter `{:?}`", key }
1584+
separate_provide_extern
15841585
}
15851586
query late_bound_vars_map(_: LocalDefId)
15861587
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {

compiler/rustc_middle/src/ty/generics.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
21
use crate::ty;
32
use crate::ty::subst::{Subst, SubstsRef};
43
use crate::ty::EarlyBinder;
@@ -13,7 +12,7 @@ use super::{EarlyBoundRegion, InstantiatedPredicates, ParamConst, ParamTy, Predi
1312
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
1413
pub enum GenericParamDefKind {
1514
Lifetime,
16-
Type { has_default: bool, object_lifetime_default: ObjectLifetimeDefault, synthetic: bool },
15+
Type { has_default: bool, synthetic: bool },
1716
Const { has_default: bool },
1817
}
1918

compiler/rustc_middle/src/ty/parameterized.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ trivially_parameterized_over_tcx! {
5353
crate::metadata::ModChild,
5454
crate::middle::codegen_fn_attrs::CodegenFnAttrs,
5555
crate::middle::exported_symbols::SymbolExportInfo,
56+
crate::middle::resolve_lifetime::ObjectLifetimeDefault,
5657
crate::mir::ConstQualifs,
5758
ty::Generics,
5859
ty::ImplPolarity,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_hir::intravisit::{self, Visitor};
1616
use rustc_hir::{self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID};
1717
use rustc_hir::{MethodKind, Target};
1818
use rustc_middle::hir::nested_filter;
19+
use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
1920
use rustc_middle::ty::query::Providers;
2021
use rustc_middle::ty::TyCtxt;
2122
use rustc_session::lint::builtin::{
@@ -171,6 +172,9 @@ impl CheckAttrVisitor<'_> {
171172
sym::no_implicit_prelude => {
172173
self.check_generic_attr(hir_id, attr, target, &[Target::Mod])
173174
}
175+
sym::rustc_object_lifetime_default => {
176+
self.check_object_lifetime_default(hir_id, span)
177+
}
174178
_ => {}
175179
}
176180

@@ -402,6 +406,30 @@ impl CheckAttrVisitor<'_> {
402406
}
403407
}
404408

409+
/// Debugging aid for `object_lifetime_default` query.
410+
fn check_object_lifetime_default(&self, hir_id: HirId, span: Span) {
411+
let tcx = self.tcx;
412+
if let Some(generics) = tcx.hir().get_generics(tcx.hir().local_def_id(hir_id)) {
413+
let object_lifetime_default_reprs: String = generics
414+
.params
415+
.iter()
416+
.filter_map(|p| {
417+
let param_id = tcx.hir().local_def_id(p.hir_id);
418+
let default = tcx.object_lifetime_default(param_id)?;
419+
Some(match default {
420+
ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
421+
ObjectLifetimeDefault::Static => "'static".to_owned(),
422+
ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
423+
ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
424+
})
425+
})
426+
.collect::<Vec<String>>()
427+
.join(",");
428+
429+
tcx.sess.span_err(span, &object_lifetime_default_reprs);
430+
}
431+
}
432+
405433
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
406434
fn check_track_caller(
407435
&self,

compiler/rustc_resolve/src/late/lifetimes.rs

Lines changed: 24 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,10 @@ use rustc_middle::bug;
1818
use rustc_middle::hir::map::Map;
1919
use rustc_middle::hir::nested_filter;
2020
use rustc_middle::middle::resolve_lifetime::*;
21-
use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
21+
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
2222
use rustc_span::def_id::DefId;
2323
use rustc_span::symbol::{sym, Ident};
2424
use rustc_span::Span;
25-
use std::borrow::Cow;
2625
use std::fmt;
2726

2827
trait RegionExt {
@@ -290,7 +289,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
290289

291290
named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
292291
is_late_bound_map,
293-
object_lifetime_defaults,
292+
object_lifetime_default,
294293
late_bound_vars_map: |tcx, id| resolve_lifetimes_for(tcx, id).late_bound_vars.get(&id),
295294

296295
..*providers
@@ -1264,87 +1263,36 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
12641263
}
12651264
}
12661265

1267-
fn object_lifetime_defaults<'tcx>(
1266+
fn object_lifetime_default<'tcx>(
12681267
tcx: TyCtxt<'tcx>,
1269-
def_id: LocalDefId,
1270-
) -> Option<&'tcx [ObjectLifetimeDefault]> {
1271-
let hir::Node::Item(item) = tcx.hir().get_by_def_id(def_id) else { return None; };
1272-
match item.kind {
1273-
hir::ItemKind::Struct(_, ref generics)
1274-
| hir::ItemKind::Union(_, ref generics)
1275-
| hir::ItemKind::Enum(_, ref generics)
1276-
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
1277-
ref generics,
1278-
origin: hir::OpaqueTyOrigin::TyAlias,
1279-
..
1280-
})
1281-
| hir::ItemKind::TyAlias(_, ref generics)
1282-
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
1283-
let result = object_lifetime_defaults_for_item(tcx, generics);
1284-
1285-
// Debugging aid.
1286-
let attrs = tcx.hir().attrs(item.hir_id());
1287-
if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
1288-
let object_lifetime_default_reprs: String = result
1289-
.iter()
1290-
.map(|set| match *set {
1291-
ObjectLifetimeDefault::Empty => "BaseDefault".into(),
1292-
ObjectLifetimeDefault::Static => "'static".into(),
1293-
ObjectLifetimeDefault::Param(def_id) => {
1294-
let def_id = def_id.expect_local();
1295-
tcx.hir().ty_param_name(def_id).to_string().into()
1296-
}
1297-
ObjectLifetimeDefault::Ambiguous => "Ambiguous".into(),
1298-
})
1299-
.collect::<Vec<Cow<'static, str>>>()
1300-
.join(",");
1301-
tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
1302-
}
1303-
1304-
Some(result)
1305-
}
1306-
_ => None,
1307-
}
1308-
}
1309-
1310-
/// Scan the bounds and where-clauses on parameters to extract bounds
1311-
/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
1312-
/// for each type parameter.
1313-
fn object_lifetime_defaults_for_item<'tcx>(
1314-
tcx: TyCtxt<'tcx>,
1315-
generics: &hir::Generics<'_>,
1316-
) -> &'tcx [ObjectLifetimeDefault] {
1317-
fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
1318-
for bound in bounds {
1319-
if let hir::GenericBound::Outlives(ref lifetime) = *bound {
1320-
set.insert(lifetime.name.normalize_to_macros_2_0());
1321-
}
1322-
}
1323-
}
1324-
1325-
let process_param = |param: &hir::GenericParam<'_>| match param.kind {
1268+
param_def_id: DefId,
1269+
) -> Option<ObjectLifetimeDefault> {
1270+
let param_def_id = param_def_id.expect_local();
1271+
let parent_def_id = tcx.local_parent(param_def_id);
1272+
let generics = tcx.hir().get_generics(parent_def_id)?;
1273+
let param_hir_id = tcx.local_def_id_to_hir_id(param_def_id);
1274+
let param = generics.params.iter().find(|p| p.hir_id == param_hir_id)?;
1275+
1276+
// Scan the bounds and where-clauses on parameters to extract bounds
1277+
// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
1278+
// for each type parameter.
1279+
match param.kind {
13261280
GenericParamKind::Lifetime { .. } => None,
13271281
GenericParamKind::Type { .. } => {
13281282
let mut set = Set1::Empty;
13291283

1330-
let param_def_id = tcx.hir().local_def_id(param.hir_id);
1331-
for predicate in generics.predicates {
1332-
// Look for `type: ...` where clauses.
1333-
let hir::WherePredicate::BoundPredicate(ref data) = *predicate else { continue };
1334-
1284+
// Look for `type: ...` where clauses.
1285+
for bound in generics.bounds_for_param(param_def_id) {
13351286
// Ignore `for<'a> type: ...` as they can change what
13361287
// lifetimes mean (although we could "just" handle it).
1337-
if !data.bound_generic_params.is_empty() {
1288+
if !bound.bound_generic_params.is_empty() {
13381289
continue;
13391290
}
13401291

1341-
let res = match data.bounded_ty.kind {
1342-
hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
1343-
_ => continue,
1344-
};
1345-
1346-
if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
1347-
add_bounds(&mut set, &data.bounds);
1292+
for bound in bound.bounds {
1293+
if let hir::GenericBound::Outlives(ref lifetime) = *bound {
1294+
set.insert(lifetime.name.normalize_to_macros_2_0());
1295+
}
13481296
}
13491297
}
13501298

@@ -1364,9 +1312,7 @@ fn object_lifetime_defaults_for_item<'tcx>(
13641312
// in an arbitrary order.
13651313
Some(ObjectLifetimeDefault::Empty)
13661314
}
1367-
};
1368-
1369-
tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
1315+
}
13701316
}
13711317

13721318
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
@@ -1744,13 +1690,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
17441690
generics
17451691
.params
17461692
.iter()
1747-
.filter_map(|param| match param.kind {
1748-
GenericParamDefKind::Type { object_lifetime_default, .. } => {
1749-
Some(object_lifetime_default)
1750-
}
1751-
GenericParamDefKind::Const { .. } => Some(ObjectLifetimeDefault::Empty),
1752-
GenericParamDefKind::Lifetime => None,
1753-
})
1693+
.filter_map(|param| self.tcx.object_lifetime_default(param.def_id))
17541694
.map(set_to_region)
17551695
.collect()
17561696
});

compiler/rustc_typeck/src/collect.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use rustc_hir::weak_lang_items;
3434
use rustc_hir::{GenericParamKind, HirId, Node};
3535
use rustc_middle::hir::nested_filter;
3636
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
37-
use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
3837
use rustc_middle::mir::mono::Linkage;
3938
use rustc_middle::ty::query::Providers;
4039
use rustc_middle::ty::subst::InternalSubsts;
@@ -1598,7 +1597,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
15981597
pure_wrt_drop: false,
15991598
kind: ty::GenericParamDefKind::Type {
16001599
has_default: false,
1601-
object_lifetime_default: ObjectLifetimeDefault::Empty,
16021600
synthetic: false,
16031601
},
16041602
});
@@ -1642,8 +1640,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16421640
kind: ty::GenericParamDefKind::Lifetime,
16431641
}));
16441642

1645-
let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner);
1646-
16471643
// Now create the real type and const parameters.
16481644
let type_start = own_start - has_self as u32 + params.len() as u32;
16491645
let mut i = 0;
@@ -1668,13 +1664,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16681664
}
16691665
}
16701666

1671-
let kind = ty::GenericParamDefKind::Type {
1672-
has_default: default.is_some(),
1673-
object_lifetime_default: object_lifetime_defaults
1674-
.as_ref()
1675-
.map_or(ObjectLifetimeDefault::Empty, |o| o[i]),
1676-
synthetic,
1677-
};
1667+
let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
16781668

16791669
let param_def = ty::GenericParamDef {
16801670
index: type_start + i as u32,
@@ -1726,11 +1716,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17261716
name: Symbol::intern(arg),
17271717
def_id,
17281718
pure_wrt_drop: false,
1729-
kind: ty::GenericParamDefKind::Type {
1730-
has_default: false,
1731-
object_lifetime_default: ObjectLifetimeDefault::Empty,
1732-
synthetic: false,
1733-
},
1719+
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
17341720
}));
17351721
}
17361722

@@ -1743,11 +1729,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17431729
name: Symbol::intern("<const_ty>"),
17441730
def_id,
17451731
pure_wrt_drop: false,
1746-
kind: ty::GenericParamDefKind::Type {
1747-
has_default: false,
1748-
object_lifetime_default: ObjectLifetimeDefault::Empty,
1749-
synthetic: false,
1750-
},
1732+
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
17511733
});
17521734
}
17531735
}

0 commit comments

Comments
 (0)