Skip to content

Commit ef2a611

Browse files
Simplify via map_rpit_lifetime_to_fn_lifetime
1 parent 67703b9 commit ef2a611

File tree

2 files changed

+21
-145
lines changed

2 files changed

+21
-145
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+11-144
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor;
1313
use rustc_hir::{ItemKind, Node, PathSegment};
1414
use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
1515
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
16-
use rustc_infer::infer::{LateBoundRegionConversionTime, RegionVariableOrigin, TyCtxtInferExt};
16+
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
1717
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
1818
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
1919
use rustc_middle::hir::nested_filter;
@@ -407,38 +407,17 @@ fn check_opaque_meets_bounds<'tcx>(
407407
.build();
408408
let ocx = ObligationCtxt::new(&infcx);
409409

410-
let mut args = GenericArgs::identity_for_item(tcx, def_id.to_def_id());
411-
assert!(!args.has_escaping_bound_vars(), "{args:#?}");
412-
if let hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) = origin {
413-
// Find use of the RPIT in the function signature and thus find the right args to
414-
// convert it into the parameter space of the function signature. This is needed,
415-
// because that's what `type_of` returns, against which we compare later.
416-
let ret = tcx.fn_sig(defining_use_anchor).instantiate_identity().output();
417-
418-
let a = ret
419-
.skip_binder()
420-
.visit_with(&mut FindOpaqueTypeArgs {
410+
let args = match *origin {
411+
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
412+
GenericArgs::identity_for_item(tcx, parent).extend_to(
421413
tcx,
422-
opaque: def_id.to_def_id(),
423-
fn_def_id: defining_use_anchor.to_def_id(),
424-
seen: Default::default(),
425-
depth: ty::INNERMOST,
426-
})
427-
.break_value()
428-
.ok_or_else(|| {
429-
tcx.sess.delay_span_bug(
430-
tcx.def_span(defining_use_anchor),
431-
format!("return type of {defining_use_anchor:?} does not contain {def_id:?}"),
432-
)
433-
})?;
434-
let a = infcx.instantiate_binder_with_fresh_vars(
435-
span,
436-
LateBoundRegionConversionTime::HigherRankedType,
437-
ret.rebind(a),
438-
);
439-
assert!(!a.has_escaping_bound_vars(), "{a:#?}");
440-
args = ty::EarlyBinder::bind(args).instantiate(tcx, a);
441-
}
414+
def_id.to_def_id(),
415+
|param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
416+
)
417+
}
418+
hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
419+
};
420+
442421
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
443422

444423
// `ReErased` regions appear in the "parent_args" of closures/generators.
@@ -551,118 +530,6 @@ fn sanity_check_found_hidden_type<'tcx>(
551530
}
552531
}
553532

554-
/// In case it is in a nested opaque type, find that opaque type's
555-
/// usage in the function signature and use the generic arguments from the usage site.
556-
/// We need to do because RPITs ignore the lifetimes of the function,
557-
/// as they have their own copies of all the lifetimes they capture.
558-
/// So the only way to get the lifetimes represented in terms of the function,
559-
/// is to look how they are used in the function signature (or do some other fancy
560-
/// recording of this mapping at ast -> hir lowering time).
561-
///
562-
/// As an example:
563-
/// ```text
564-
/// trait Id {
565-
/// type Assoc;
566-
/// }
567-
/// impl<'a> Id for &'a () {
568-
/// type Assoc = &'a ();
569-
/// }
570-
/// fn func<'a>(x: &'a ()) -> impl Id<Assoc = impl Sized + 'a> { x }
571-
/// // desugared to
572-
/// fn func<'a>(x: &'a () -> Outer<'a> where <Outer<'a> as Id>::Assoc = Inner<'a> {
573-
/// // Note that in contrast to other nested items, RPIT type aliases can
574-
/// // access their parents' generics.
575-
///
576-
/// // hidden type is `&'aDupOuter ()`
577-
/// // During wfcheck the hidden type of `Inner<'aDupOuter>` is `&'a ()`, but
578-
/// // `typeof(Inner<'aDupOuter>) = &'aDupOuter ()`.
579-
/// // So we walk the signature of `func` to find the use of `Inner<'a>`
580-
/// // and then use that to replace the lifetimes in the hidden type, obtaining
581-
/// // `&'a ()`.
582-
/// type Outer<'aDupOuter> = impl Id<Assoc = Inner<'aDupOuter>>;
583-
///
584-
/// // hidden type is `&'aDupInner ()`
585-
/// type Inner<'aDupInner> = impl Sized + 'aDupInner;
586-
///
587-
/// x
588-
/// }
589-
/// ```
590-
struct FindOpaqueTypeArgs<'tcx> {
591-
tcx: TyCtxt<'tcx>,
592-
opaque: DefId,
593-
seen: FxHashSet<DefId>,
594-
fn_def_id: DefId,
595-
depth: ty::DebruijnIndex,
596-
}
597-
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for FindOpaqueTypeArgs<'tcx> {
598-
type BreakTy = GenericArgsRef<'tcx>;
599-
600-
#[instrument(level = "trace", skip(self), ret)]
601-
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
602-
&mut self,
603-
t: &ty::Binder<'tcx, T>,
604-
) -> ControlFlow<Self::BreakTy> {
605-
self.depth.shift_in(1);
606-
let binder = t.super_visit_with(self);
607-
self.depth.shift_out(1);
608-
binder
609-
}
610-
611-
#[instrument(level = "trace", skip(self), ret)]
612-
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
613-
trace!("{:#?}", t.kind());
614-
match t.kind() {
615-
ty::Alias(ty::Opaque, alias) => {
616-
trace!(?alias.def_id);
617-
if alias.def_id == self.opaque {
618-
let args = self.tcx.fold_regions(alias.args, |re, depth| {
619-
if let ty::ReLateBound(index, bv) = re.kind() {
620-
if depth != ty::INNERMOST {
621-
return ty::Region::new_error_with_message(
622-
self.tcx,
623-
self.tcx.def_span(self.opaque),
624-
"opaque type behind meaningful binders are not supported yet",
625-
);
626-
}
627-
ty::Region::new_late_bound(
628-
self.tcx,
629-
index.shifted_out_to_binder(self.depth),
630-
bv,
631-
)
632-
} else {
633-
re
634-
}
635-
});
636-
return ControlFlow::Break(args);
637-
} else if self.seen.insert(alias.def_id) {
638-
for clause in self
639-
.tcx
640-
.explicit_item_bounds(alias.def_id)
641-
.iter_instantiated_copied(self.tcx, alias.args)
642-
{
643-
trace!(?clause);
644-
clause.visit_with(self)?;
645-
}
646-
}
647-
}
648-
ty::Alias(ty::Projection, alias) => {
649-
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, .. }) = self.tcx.opt_rpitit_info(alias.def_id) && fn_def_id == self.fn_def_id {
650-
self.tcx.type_of(alias.def_id).instantiate(self.tcx, alias.args).visit_with(self)?;
651-
}
652-
}
653-
ty::Alias(ty::Weak, alias) => {
654-
self.tcx
655-
.type_of(alias.def_id)
656-
.instantiate(self.tcx, alias.args)
657-
.visit_with(self)?;
658-
}
659-
_ => (),
660-
}
661-
662-
t.super_visit_with(self)
663-
}
664-
}
665-
666533
fn is_enum_of_nonnullable_ptr<'tcx>(
667534
tcx: TyCtxt<'tcx>,
668535
adt_def: AdtDef<'tcx>,

compiler/rustc_middle/src/ty/context.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1995,7 +1995,16 @@ impl<'tcx> TyCtxt<'tcx> {
19951995
),
19961996
);
19971997
}
1998-
_ => bug!(),
1998+
Some(resolve_bound_vars::ResolvedArg::Error(guar)) => {
1999+
return ty::Region::new_error(self, guar);
2000+
}
2001+
_ => {
2002+
return ty::Region::new_error_with_message(
2003+
self,
2004+
lifetime.ident.span,
2005+
"cannot resolve lifetime",
2006+
);
2007+
}
19992008
}
20002009
}
20012010
}

0 commit comments

Comments
 (0)