From 298bfd6d1e2038c18e2331ac00e4409517dc8f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 27 Dec 2023 15:52:39 +0100 Subject: [PATCH] Update comments and variable names --- .../src/outlives/implicit_infer.rs | 78 +++++++++---------- .../rustc_hir_analysis/src/outlives/mod.rs | 4 +- 2 files changed, 37 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs index f0eb75237c73a..8ecc0389d3e2f 100644 --- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs +++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs @@ -99,14 +99,14 @@ 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>>, 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 @@ -114,54 +114,49 @@ fn insert_required_predicates_to_be_wf<'tcx>( 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: + // Example: // - // 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, ); @@ -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(), @@ -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 @@ -209,14 +200,15 @@ fn insert_required_predicates_to_be_wf<'tcx>( } } - ty::Alias(ty::Projection, obj) => { - // This corresponds to `>::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, @@ -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, _) => {} _ => {} diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index 6b69265c53932..4b3de52dc3ddd 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -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