Skip to content

Commit 7c1a8d8

Browse files
committed
Compute object_lifetime_default per parameter.
1 parent d63dda2 commit 7c1a8d8

File tree

9 files changed

+65
-97
lines changed

9 files changed

+65
-97
lines changed

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

+1
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

+5
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
10351035
record_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
10361036
}
10371037
}
1038+
if let DefKind::TyParam | DefKind::ConstParam = def_kind {
1039+
if let Some(default) = self.tcx.object_lifetime_default(def_id) {
1040+
record!(self.tables.object_lifetime_default[def_id] <- default);
1041+
}
1042+
}
10381043
if let DefKind::Trait | DefKind::TraitAlias = def_kind {
10391044
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
10401045
}

compiler/rustc_metadata/src/rmeta/mod.rs

+2
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::thir;
2122
use rustc_middle::ty::fast_reject::SimplifiedType;
@@ -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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1591,8 +1591,9 @@ rustc_queries! {
15911591
/// for each parameter if a trait object were to be passed for that parameter.
15921592
/// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
15931593
/// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
1594-
query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
1594+
query object_lifetime_default(_: DefId) -> Option<ObjectLifetimeDefault> {
15951595
desc { "looking up lifetime defaults for a region on an item" }
1596+
separate_provide_extern
15961597
}
15971598
/// Fetch the lifetimes for all the trait objects in an item-like.
15981599
query object_lifetime_map(_: LocalDefId) -> FxHashMap<ItemLocalId, ty::Region<'tcx>> {

compiler/rustc_middle/src/ty/generics.rs

+1-2
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

+1
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

+28
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::{
@@ -164,6 +165,9 @@ impl CheckAttrVisitor<'_> {
164165
sym::no_implicit_prelude => {
165166
self.check_generic_attr(hir_id, attr, target, &[Target::Mod])
166167
}
168+
sym::rustc_object_lifetime_default => {
169+
self.check_object_lifetime_default(hir_id, span)
170+
}
167171
_ => {}
168172
}
169173

@@ -368,6 +372,30 @@ impl CheckAttrVisitor<'_> {
368372
}
369373
}
370374

375+
/// Debugging aid for `object_lifetime_default` query.
376+
fn check_object_lifetime_default(&self, hir_id: HirId, span: Span) {
377+
let tcx = self.tcx;
378+
if let Some(generics) = tcx.hir().get_generics(tcx.hir().local_def_id(hir_id)) {
379+
let object_lifetime_default_reprs: String = generics
380+
.params
381+
.iter()
382+
.filter_map(|p| {
383+
let param_id = tcx.hir().local_def_id(p.hir_id);
384+
let default = tcx.object_lifetime_default(param_id)?;
385+
Some(match default {
386+
ObjectLifetimeDefault::Empty => "BaseDefault".to_owned(),
387+
ObjectLifetimeDefault::Static => "'static".to_owned(),
388+
ObjectLifetimeDefault::Param(def_id) => tcx.item_name(def_id).to_string(),
389+
ObjectLifetimeDefault::Ambiguous => "Ambiguous".to_owned(),
390+
})
391+
})
392+
.collect::<Vec<String>>()
393+
.join(",");
394+
395+
tcx.sess.span_err(span, &object_lifetime_default_reprs);
396+
}
397+
}
398+
371399
/// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid.
372400
fn check_track_caller(
373401
&self,

compiler/rustc_typeck/src/collect.rs

+4-22
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use rustc_hir::weak_lang_items;
3535
use rustc_hir::{GenericParamKind, HirId, Node};
3636
use rustc_middle::hir::nested_filter;
3737
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
38-
use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
3938
use rustc_middle::mir::mono::Linkage;
4039
use rustc_middle::ty::query::Providers;
4140
use rustc_middle::ty::subst::InternalSubsts;
@@ -71,7 +70,7 @@ pub fn provide(providers: &mut Providers) {
7170
type_of: type_of::type_of,
7271
item_bounds: item_bounds::item_bounds,
7372
explicit_item_bounds: item_bounds::explicit_item_bounds,
74-
object_lifetime_defaults: object_lifetime_defaults::object_lifetime_defaults,
73+
object_lifetime_default: object_lifetime_defaults::object_lifetime_default,
7574
object_lifetime_map: object_lifetime_defaults::object_lifetime_map,
7675
generics_of,
7776
predicates_of,
@@ -1638,7 +1637,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16381637
pure_wrt_drop: false,
16391638
kind: ty::GenericParamDefKind::Type {
16401639
has_default: false,
1641-
object_lifetime_default: ObjectLifetimeDefault::Empty,
16421640
synthetic: false,
16431641
},
16441642
});
@@ -1686,8 +1684,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
16861684
kind: ty::GenericParamDefKind::Lifetime,
16871685
}));
16881686

1689-
let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner);
1690-
16911687
// Now create the real type and const parameters.
16921688
let type_start = own_start - has_self as u32 + params.len() as u32;
16931689
let mut i = 0;
@@ -1712,13 +1708,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17121708
}
17131709
}
17141710

1715-
let kind = ty::GenericParamDefKind::Type {
1716-
has_default: default.is_some(),
1717-
object_lifetime_default: object_lifetime_defaults
1718-
.as_ref()
1719-
.map_or(ObjectLifetimeDefault::Empty, |o| o[i]),
1720-
synthetic,
1721-
};
1711+
let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic };
17221712

17231713
let param_def = ty::GenericParamDef {
17241714
index: type_start + i as u32,
@@ -1766,11 +1756,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17661756
name: Symbol::intern(arg),
17671757
def_id,
17681758
pure_wrt_drop: false,
1769-
kind: ty::GenericParamDefKind::Type {
1770-
has_default: false,
1771-
object_lifetime_default: ObjectLifetimeDefault::Empty,
1772-
synthetic: false,
1773-
},
1759+
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
17741760
}));
17751761
}
17761762

@@ -1783,11 +1769,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
17831769
name: Symbol::intern("<const_ty>"),
17841770
def_id,
17851771
pure_wrt_drop: false,
1786-
kind: ty::GenericParamDefKind::Type {
1787-
has_default: false,
1788-
object_lifetime_default: ObjectLifetimeDefault::Empty,
1789-
synthetic: false,
1790-
},
1772+
kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false },
17911773
});
17921774
}
17931775
}

compiler/rustc_typeck/src/collect/object_lifetime_defaults.rs

+21-72
Original file line numberDiff line numberDiff line change
@@ -2,84 +2,33 @@ use crate::AstConv;
22
use rustc_data_structures::fx::FxHashMap;
33
use rustc_hir as hir;
44
use rustc_hir::def::{DefKind, Res};
5-
use rustc_hir::def_id::LocalDefId;
5+
use rustc_hir::def_id::{DefId, LocalDefId};
66
use rustc_hir::hir_id::ItemLocalId;
77
use rustc_hir::intravisit::{self, Visitor};
88
use rustc_hir::{GenericArg, GenericParamKind, LifetimeName, Node};
99
use rustc_middle::bug;
1010
use rustc_middle::hir::nested_filter;
1111
use rustc_middle::middle::resolve_lifetime::*;
1212
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
13-
use rustc_span::symbol::sym;
14-
use std::borrow::Cow;
1513

1614
use tracing::debug;
1715

18-
pub(super) fn object_lifetime_defaults(
16+
pub(super) fn object_lifetime_default(
1917
tcx: TyCtxt<'_>,
20-
def_id: LocalDefId,
21-
) -> Option<&[ObjectLifetimeDefault]> {
22-
let Node::Item(item) = tcx.hir().get_by_def_id(def_id) else { return None };
23-
match item.kind {
24-
hir::ItemKind::Struct(_, ref generics)
25-
| hir::ItemKind::Union(_, ref generics)
26-
| hir::ItemKind::Enum(_, ref generics)
27-
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
28-
ref generics,
29-
origin: hir::OpaqueTyOrigin::TyAlias,
30-
..
31-
})
32-
| hir::ItemKind::TyAlias(_, ref generics)
33-
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
34-
let result = object_lifetime_defaults_for_item(tcx, generics);
35-
debug!(?result);
36-
37-
// Debugging aid.
38-
let attrs = tcx.hir().attrs(item.hir_id());
39-
if tcx.sess.contains_name(attrs, sym::rustc_object_lifetime_default) {
40-
let object_lifetime_default_reprs: String = result
41-
.iter()
42-
.map(|set| match *set {
43-
ObjectLifetimeDefault::Empty => "BaseDefault".into(),
44-
ObjectLifetimeDefault::Static => "'static".into(),
45-
ObjectLifetimeDefault::Param(def_id) => {
46-
let def_id = def_id.expect_local();
47-
generics
48-
.params
49-
.iter()
50-
.find(|param| tcx.hir().local_def_id(param.hir_id) == def_id)
51-
.map(|param| param.name.ident().to_string().into())
52-
.unwrap()
53-
}
54-
ObjectLifetimeDefault::Ambiguous => "Ambiguous".into(),
55-
})
56-
.collect::<Vec<Cow<'static, str>>>()
57-
.join(",");
58-
tcx.sess.span_err(item.span, &object_lifetime_default_reprs);
59-
}
18+
param_def_id: DefId,
19+
) -> Option<ObjectLifetimeDefault> {
20+
let param_def_id = param_def_id.expect_local();
21+
let parent_item_id = tcx.local_parent(param_def_id);
22+
let generics = tcx.hir().get_generics(parent_item_id)?;
6023

61-
Some(result)
62-
}
63-
_ => None,
64-
}
65-
}
24+
// Scan the bounds and where-clauses on parameters to extract bounds
25+
// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
26+
// for each type parameter.
6627

67-
/// Scan the bounds and where-clauses on parameters to extract bounds
68-
/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
69-
/// for each type parameter.
70-
fn object_lifetime_defaults_for_item<'tcx>(
71-
tcx: TyCtxt<'tcx>,
72-
generics: &hir::Generics<'_>,
73-
) -> &'tcx [ObjectLifetimeDefault] {
74-
fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
75-
for bound in bounds {
76-
if let hir::GenericBound::Outlives(ref lifetime) = *bound {
77-
set.insert(lifetime.name.normalize_to_macros_2_0());
78-
}
79-
}
80-
}
28+
let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_def_id);
29+
let param = generics.params.iter().find(|p| p.hir_id == param_hir_id)?;
8130

82-
let process_param = |param: &hir::GenericParam<'_>| match param.kind {
31+
match param.kind {
8332
GenericParamKind::Lifetime { .. } => None,
8433
GenericParamKind::Type { .. } => {
8534
let mut set = Set1::Empty;
@@ -101,7 +50,11 @@ fn object_lifetime_defaults_for_item<'tcx>(
10150
};
10251

10352
if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
104-
add_bounds(&mut set, &data.bounds);
53+
for bound in data.bounds {
54+
if let hir::GenericBound::Outlives(ref lifetime) = *bound {
55+
set.insert(lifetime.name.normalize_to_macros_2_0());
56+
}
57+
}
10558
}
10659
}
10760

@@ -121,9 +74,7 @@ fn object_lifetime_defaults_for_item<'tcx>(
12174
// in an arbitrary order.
12275
Some(ObjectLifetimeDefault::Empty)
12376
}
124-
};
125-
126-
tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
77+
}
12778
}
12879

12980
pub(super) fn object_lifetime_map(
@@ -466,7 +417,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
466417
// Therefore, we would compute `object_lifetime_defaults` to a
467418
// vector like `['x, 'static]`. Note that the vector only
468419
// includes type parameters.
469-
let generics = self.tcx.generics_of(type_def_id);
420+
let generics = tcx.generics_of(type_def_id);
470421

471422
let in_body = {
472423
let mut scope = self.scope;
@@ -485,9 +436,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
485436
let object_lifetime_default = |i: usize| {
486437
let param = generics.params.get(i)?;
487438
match param.kind {
488-
GenericParamDefKind::Type { object_lifetime_default, .. } => {
489-
Some(object_lifetime_default)
490-
}
439+
GenericParamDefKind::Type { .. } => tcx.object_lifetime_default(param.def_id),
491440
GenericParamDefKind::Const { .. } => Some(ObjectLifetimeDefault::Empty),
492441
GenericParamDefKind::Lifetime => return None,
493442
}

0 commit comments

Comments
 (0)