Skip to content

Commit

Permalink
Update comments and variable names
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Dec 27, 2023
1 parent 6dd1356 commit 8c9c05c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 44 deletions.
76 changes: 34 additions & 42 deletions compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,69 +99,64 @@ pub(super) fn infer_predicates(

fn insert_required_predicates_to_be_wf<'tcx>(
tcx: TyCtxt<'tcx>,
field_ty: Ty<'tcx>,
field_span: Span,
ty: Ty<'tcx>,
span: Span,
global_inferred_outlives: &FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
required_predicates: &mut RequiredPredicates<'tcx>,
explicit_map: &mut ExplicitPredicatesMap<'tcx>,
) {
for arg in field_ty.walk() {
let ty = match arg.unpack() {
for arg in ty.walk() {
let leaf_ty = match arg.unpack() {
GenericArgKind::Type(ty) => ty,

// No predicates from lifetimes or constants, except potentially
// constants' types, but `walk` will get to them as well.
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => continue,
};

match *ty.kind() {
// The field is of type &'a T which means that we will have
// a predicate requirement of T: 'a (T outlives 'a).
match *leaf_ty.kind() {
// The type is `&'a T` which means that we will have
// a predicate requirement of `T: 'a` (`T` outlives `'a`).
//
// We also want to calculate potential predicates for the T
// We also want to calculate potential predicates for the `T`.
ty::Ref(region, rty, _) => {
debug!("Ref");
insert_outlives_predicate(tcx, rty.into(), region, field_span, required_predicates);
insert_outlives_predicate(tcx, rty.into(), region, span, required_predicates);
}

// For each Adt (struct/enum/union) type `Foo<'a, T>`, we
// can load the current set of inferred and explicit
// predicates from `global_inferred_outlives` and filter the
// ones that are TypeOutlives.
// For each outer type `Outer<'a, T>`, we can load the current set of
// inferred and explicit predicates from `global_inferred_outlives` and
// filter the ones that are `TypeOutlives`.
ty::Adt(def, args) => {
// First check the inferred predicates
//
// Example 1:
//
// struct Foo<'a, T> {
// field1: Bar<'a, T>
// struct Outer<'a, T> {
// outer: Inner<'a, T>
// }
//
// struct Bar<'b, U> {
// field2: &'b U
// struct Inner<'b, U> {
// inner: &'b U
// }
//
// Here, when processing the type of `field1`, we would
// request the set of implicit predicates computed for `Bar`
// Here, when processing the type of field `outer`, we would
// request the set of implicit predicates computed for `Inner`
// thus far. This will initially come back empty, but in next
// round we will get `U: 'b`. We then apply the substitution
// `['b => 'a, U => T]` and thus get the requirement that `T:
// 'a` holds for `Foo`.
// 'a` holds for `Outer`.
debug!("Adt");
if let Some(unsubstituted_predicates) = global_inferred_outlives.get(&def.did()) {
for (unsubstituted_predicate, &span) in
unsubstituted_predicates.as_ref().skip_binder()
{
// `unsubstituted_predicate` is `U: 'b` in the
// example above. So apply the substitution to
// get `T: 'a` (or `predicate`):
let predicate = unsubstituted_predicates
.rebind(*unsubstituted_predicate)
.instantiate(tcx, args);
if let Some(predicates) = global_inferred_outlives.get(&def.did()) {
for (predicate, &span) in predicates.as_ref().skip_binder() {
// `predicate` is `U: 'b` in the example above. So apply the
// substitution to get `T: 'a` (or `instantiated_predicate`):
let instantiated_predicate =
predicates.rebind(*predicate).instantiate(tcx, args);
insert_outlives_predicate(
tcx,
predicate.0,
predicate.1,
instantiated_predicate.0,
instantiated_predicate.1,
span,
required_predicates,
);
Expand All @@ -170,7 +165,6 @@ fn insert_required_predicates_to_be_wf<'tcx>(

// Check if the type has any explicit predicates that need
// to be added to `required_predicates`
// let _: () = args.region_at(0);
check_explicit_predicates(
tcx,
def.did(),
Expand All @@ -184,10 +178,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
ty::Dynamic(obj, ..) => {
// This corresponds to `dyn Trait<..>`. In this case, we should
// use the explicit predicates as well.

debug!("Dynamic");
debug!("field_ty = {}", &field_ty);
debug!("ty in field = {}", &ty);
if let Some(ex_trait_ref) = obj.principal() {
// Here, we are passing the type `usize` as a
// placeholder value with the function
Expand All @@ -209,14 +200,15 @@ fn insert_required_predicates_to_be_wf<'tcx>(
}
}

ty::Alias(ty::Projection, obj) => {
// This corresponds to `<T as Foo<'a>>::Bar`. In this case, we should use the
// explicit predicates as well.
ty::Alias(ty::Projection, alias) => {
// This corresponds to a type like `<() as Trait<'a, T>>::Type`.
// We only use the explicit predicates of the trait but
// not the ones of the associated type itself.
debug!("Projection");
check_explicit_predicates(
tcx,
tcx.parent(obj.def_id),
obj.args,
tcx.parent(alias.def_id),
alias.args,
required_predicates,
explicit_map,
None,
Expand All @@ -238,7 +230,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
);
}

// FIXME(inherent_associated_types): Handle this case properly.
// FIXME(inherent_associated_types): Use the explicit predicates from the parent impl.
ty::Alias(ty::Inherent, _) => {}

_ => {}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau
}

fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> {
// Compute a map from each struct/enum/union S to the **explicit**
// outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote.
// Compute a map from each ADT (struct/enum/union) & lazy type alias to
// the **explicit** outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote.
// Typically there won't be many of these, except in older code where
// they were mandatory. Nonetheless, we have to ensure that every such
// predicate is satisfied, so they form a kind of base set of requirements
Expand Down

0 comments on commit 8c9c05c

Please sign in to comment.