Skip to content

Commit

Permalink
Rollup merge of rust-lang#99821 - cjgillot:ast-lifetimes-2, r=compile…
Browse files Browse the repository at this point in the history
…r-errors

Remove separate indexing of early-bound regions

~Based on rust-lang#99728

This PR copies some modifications from rust-lang#97839 around object lifetime defaults.
These modifications allow to stop counting generic parameters during lifetime resolution, and rely on the indexing given by `rustc_typeck::collect`.
  • Loading branch information
Dylan-DPC authored Aug 29, 2022
2 parents 1999ed7 + da90ec1 commit 5555e13
Show file tree
Hide file tree
Showing 17 changed files with 180 additions and 432 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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(_, _),
)
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 @@ -2026,13 +2026,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 @@ -2069,8 +2069,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,
};
Expand Down Expand Up @@ -2164,11 +2168,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, 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 @@ -1076,6 +1076,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::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::Providers;
Expand Down Expand Up @@ -358,6 +359,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 @@ -486,7 +486,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),
}
}
Expand All @@ -495,7 +497,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),
}
}
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),
Free(DefId, /* lifetime decl */ DefId),
}
Expand All @@ -35,7 +35,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
5 changes: 3 additions & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1597,8 +1597,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<ObjectLifetimeDefault> {
desc { "looking up lifetime defaults for generic parameter `{:?}`", key }
separate_provide_extern
}
query late_bound_vars_map(_: LocalDefId)
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
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 @@ -172,6 +173,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 @@ -410,6 +414,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

0 comments on commit 5555e13

Please sign in to comment.