about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-08-07 23:54:04 +0000
committerMichael Goulet <michael@errs.io>2023-08-08 09:39:42 +0000
commitef2a611803964e50853333e34d41f4347434513c (patch)
treec77aa7746dd3c18321e1c853075cda71927c1fdc /compiler
parent67703b9161e4869c5ac155e9a12317c1a2fee339 (diff)
downloadrust-ef2a611803964e50853333e34d41f4347434513c.tar.gz
rust-ef2a611803964e50853333e34d41f4347434513c.zip
Simplify via map_rpit_lifetime_to_fn_lifetime
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs155
-rw-r--r--compiler/rustc_middle/src/ty/context.rs11
2 files changed, 21 insertions, 145 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index f0a8ae9b7a8..1c4ee9a2bc3 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor;
 use rustc_hir::{ItemKind, Node, PathSegment};
 use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
-use rustc_infer::infer::{LateBoundRegionConversionTime, RegionVariableOrigin, TyCtxtInferExt};
+use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, TraitEngineExt as _};
 use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
 use rustc_middle::hir::nested_filter;
@@ -407,38 +407,17 @@ fn check_opaque_meets_bounds<'tcx>(
         .build();
     let ocx = ObligationCtxt::new(&infcx);
 
-    let mut args = GenericArgs::identity_for_item(tcx, def_id.to_def_id());
-    assert!(!args.has_escaping_bound_vars(), "{args:#?}");
-    if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin {
-        // Find use of the RPIT in the function signature and thus find the right args to
-        // convert it into the parameter space of the function signature. This is needed,
-        // because that's what `type_of` returns, against which we compare later.
-        let ret = tcx.fn_sig(defining_use_anchor).instantiate_identity().output();
-
-        let a = ret
-            .skip_binder()
-            .visit_with(&mut FindOpaqueTypeArgs {
+    let args = match *origin {
+        hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
+            GenericArgs::identity_for_item(tcx, parent).extend_to(
                 tcx,
-                opaque: def_id.to_def_id(),
-                fn_def_id: defining_use_anchor.to_def_id(),
-                seen: Default::default(),
-                depth: ty::INNERMOST,
-            })
-            .break_value()
-            .ok_or_else(|| {
-                tcx.sess.delay_span_bug(
-                    tcx.def_span(defining_use_anchor),
-                    format!("return type of {defining_use_anchor:?} does not contain {def_id:?}"),
-                )
-            })?;
-        let a = infcx.instantiate_binder_with_fresh_vars(
-            span,
-            LateBoundRegionConversionTime::HigherRankedType,
-            ret.rebind(a),
-        );
-        assert!(!a.has_escaping_bound_vars(), "{a:#?}");
-        args = ty::EarlyBinder::bind(args).instantiate(tcx, a);
-    }
+                def_id.to_def_id(),
+                |param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
+            )
+        }
+        hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
+    };
+
     let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
 
     // `ReErased` regions appear in the "parent_args" of closures/generators.
@@ -551,118 +530,6 @@ fn sanity_check_found_hidden_type<'tcx>(
     }
 }
 
-/// In case it is in a nested opaque type, find that opaque type's
-/// usage in the function signature and use the generic arguments from the usage site.
-/// We need to do because RPITs ignore the lifetimes of the function,
-/// as they have their own copies of all the lifetimes they capture.
-/// So the only way to get the lifetimes represented in terms of the function,
-/// is to look how they are used in the function signature (or do some other fancy
-/// recording of this mapping at ast -> hir lowering time).
-///
-/// As an example:
-/// ```text
-/// trait Id {
-///     type Assoc;
-/// }
-/// impl<'a> Id for &'a () {
-///     type Assoc = &'a ();
-/// }
-/// fn func<'a>(x: &'a ()) -> impl Id<Assoc = impl Sized + 'a> { x }
-/// // desugared to
-/// fn func<'a>(x: &'a () -> Outer<'a> where <Outer<'a> as Id>::Assoc = Inner<'a> {
-///     // Note that in contrast to other nested items, RPIT type aliases can
-///     // access their parents' generics.
-///
-///     // hidden type is `&'aDupOuter ()`
-///     // During wfcheck the hidden type of `Inner<'aDupOuter>` is `&'a ()`, but
-///     // `typeof(Inner<'aDupOuter>) = &'aDupOuter ()`.
-///     // So we walk the signature of `func` to find the use of `Inner<'a>`
-///     // and then use that to replace the lifetimes in the hidden type, obtaining
-///     // `&'a ()`.
-///     type Outer<'aDupOuter> = impl Id<Assoc = Inner<'aDupOuter>>;
-///
-///     // hidden type is `&'aDupInner ()`
-///     type Inner<'aDupInner> = impl Sized + 'aDupInner;
-///
-///     x
-/// }
-/// ```
-struct FindOpaqueTypeArgs<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    opaque: DefId,
-    seen: FxHashSet<DefId>,
-    fn_def_id: DefId,
-    depth: ty::DebruijnIndex,
-}
-impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for FindOpaqueTypeArgs<'tcx> {
-    type BreakTy = GenericArgsRef<'tcx>;
-
-    #[instrument(level = "trace", skip(self), ret)]
-    fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
-        &mut self,
-        t: &ty::Binder<'tcx, T>,
-    ) -> ControlFlow<Self::BreakTy> {
-        self.depth.shift_in(1);
-        let binder = t.super_visit_with(self);
-        self.depth.shift_out(1);
-        binder
-    }
-
-    #[instrument(level = "trace", skip(self), ret)]
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-        trace!("{:#?}", t.kind());
-        match t.kind() {
-            ty::Alias(ty::Opaque, alias) => {
-                trace!(?alias.def_id);
-                if alias.def_id == self.opaque {
-                    let args = self.tcx.fold_regions(alias.args, |re, depth| {
-                        if let ty::ReLateBound(index, bv) = re.kind() {
-                            if depth != ty::INNERMOST {
-                                return ty::Region::new_error_with_message(
-                                    self.tcx,
-                                    self.tcx.def_span(self.opaque),
-                                    "opaque type behind meaningful binders are not supported yet",
-                                );
-                            }
-                            ty::Region::new_late_bound(
-                                self.tcx,
-                                index.shifted_out_to_binder(self.depth),
-                                bv,
-                            )
-                        } else {
-                            re
-                        }
-                    });
-                    return ControlFlow::Break(args);
-                } else if self.seen.insert(alias.def_id) {
-                    for clause in self
-                        .tcx
-                        .explicit_item_bounds(alias.def_id)
-                        .iter_instantiated_copied(self.tcx, alias.args)
-                    {
-                        trace!(?clause);
-                        clause.visit_with(self)?;
-                    }
-                }
-            }
-            ty::Alias(ty::Projection, alias) => {
-                if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = self.tcx.opt_rpitit_info(alias.def_id) && fn_def_id == self.fn_def_id {
-                    self.tcx.type_of(alias.def_id).instantiate(self.tcx, alias.args).visit_with(self)?;
-                }
-            }
-            ty::Alias(ty::Weak, alias) => {
-                self.tcx
-                    .type_of(alias.def_id)
-                    .instantiate(self.tcx, alias.args)
-                    .visit_with(self)?;
-            }
-            _ => (),
-        }
-
-        t.super_visit_with(self)
-    }
-}
-
 fn is_enum_of_nonnullable_ptr<'tcx>(
     tcx: TyCtxt<'tcx>,
     adt_def: AdtDef<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 75a2c6cbd20..e25ca75bba8 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1995,7 +1995,16 @@ impl<'tcx> TyCtxt<'tcx> {
                         ),
                     );
                 }
-                _ => bug!(),
+                Some(resolve_bound_vars::ResolvedArg::Error(guar)) => {
+                    return ty::Region::new_error(self, guar);
+                }
+                _ => {
+                    return ty::Region::new_error_with_message(
+                        self,
+                        lifetime.ident.span,
+                        "cannot resolve lifetime",
+                    );
+                }
             }
         }
     }