diff options
| author | Michael Goulet <michael@errs.io> | 2023-08-07 23:54:04 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-08-08 09:39:42 +0000 |
| commit | ef2a611803964e50853333e34d41f4347434513c (patch) | |
| tree | c77aa7746dd3c18321e1c853075cda71927c1fdc /compiler | |
| parent | 67703b9161e4869c5ac155e9a12317c1a2fee339 (diff) | |
| download | rust-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.rs | 155 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 11 |
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", + ); + } } } } |
