Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate object lifetime default from lifetime resolution #97393

Closed
wants to merge 13 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,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);
Expand Down Expand Up @@ -150,7 +150,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
Some(
rl::Region::Static
| rl::Region::Free(_, _)
| rl::Region::EarlyBound(_, _)
| rl::Region::EarlyBound(_)
| rl::Region::LateBound(_, _, _)
| rl::Region::LateBoundAnon(_, _, _),
)
Expand Down Expand Up @@ -216,7 +216,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
}
}

(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;
Expand All @@ -237,7 +237,7 @@ impl<'tcx> Visitor<'tcx> for TyPathVisitor<'tcx> {
(
Some(
rl::Region::Static
| rl::Region::EarlyBound(_, _)
| rl::Region::EarlyBound(_)
| rl::Region::LateBound(_, _, _)
| rl::Region::LateBoundAnon(_, _, _)
| rl::Region::Free(_, _),
Expand Down
19 changes: 13 additions & 6 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2050,13 +2050,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<ty::Region<'tcx>> {
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,
Expand Down Expand Up @@ -2097,8 +2097,12 @@ impl ExplicitOutlivesRequirements {
Some(Region::Static) if infer_static => {
inferred_outlives.iter().any(|r| matches!(**r, ty::ReStatic))
}
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,
};
Expand Down Expand Up @@ -2193,11 +2197,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,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,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));
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::thir;
use rustc_middle::ty::fast_reject::SimplifiedType;
Expand Down Expand Up @@ -357,6 +358,7 @@ define_tables! {
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,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::TyParam | DefKind::ConstParam | DefKind::LifetimeParam => {
self.tcx.local_parent(def_id)
}
_ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind),
}
}
Expand All @@ -555,7 +557,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::TyParam | DefKind::ConstParam | DefKind::LifetimeParam => {
self.tcx.item_name(def_id.to_def_id())
}
_ => bug!("ty_param_name: {:?} is a {:?} not a type parameter", def_id, def_kind),
}
}
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_middle/src/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
LateBoundAnon(ty::DebruijnIndex, /* late-bound index */ u32, /* anon index */ u32),
Free(DefId, /* lifetime decl */ DefId),
Expand Down Expand Up @@ -50,7 +50,13 @@ impl<T: PartialEq> Set1<T> {
}
}

pub type ObjectLifetimeDefault = Set1<Region>;
#[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.
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1591,7 +1591,13 @@ 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]`.
Comment on lines 1591 to 1593
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this comment is still true?

query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
query object_lifetime_default(_: DefId) -> Option<ObjectLifetimeDefault> {
desc { "looking up lifetime defaults for a region on an item" }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
desc { "looking up lifetime defaults for a region on an item" }
desc { "compute object lifetime defaults for a generic parameter" }

separate_provide_extern
}
/// Fetch the lifetimes for all the trait objects in an item-like.
query object_lifetime_map(_: LocalDefId) -> FxHashMap<ItemLocalId, ty::Region<'tcx>> {
storage(ArenaCacheSelector<'tcx>)
desc { "looking up lifetime defaults for a region on an item" }
}
query late_bound_vars_map(_: LocalDefId)
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/ty/generics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
use crate::ty;
use crate::ty::subst::{Subst, SubstsRef};
use crate::ty::EarlyBinder;
Expand All @@ -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 },
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/parameterized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
28 changes: 28 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -164,6 +165,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)
}
_ => {}
}

Expand Down Expand Up @@ -368,6 +372,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::<Vec<String>>()
.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,
Expand Down
Loading