Auto merge of #108700 - spastorino:new-rpitit-impl-side-2, r=compiler-errors
Make RPITITs simple cases work when using lower_impl_trait_in_trait_to_assoc_ty r? `@compiler-errors` It's probably best reviewed commit by commit.
This commit is contained in:
commit
9455a5591b
11 changed files with 164 additions and 35 deletions
|
@ -3048,10 +3048,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
&hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
|
||||
let opaque_ty = tcx.hir().item(item_id);
|
||||
let def_id = item_id.owner_id.to_def_id();
|
||||
|
||||
match opaque_ty.kind {
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
||||
let local_def_id = item_id.owner_id.def_id;
|
||||
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
|
||||
// generate the def_id of an associated type for the trait and return as
|
||||
// type a projection.
|
||||
let def_id = if in_trait && tcx.lower_impl_trait_in_trait_to_assoc_ty() {
|
||||
tcx.associated_item_for_impl_trait_in_trait(local_def_id).to_def_id()
|
||||
} else {
|
||||
local_def_id.to_def_id()
|
||||
};
|
||||
self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
|
||||
}
|
||||
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||
|
|
|
@ -830,7 +830,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
|
|||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if let ty::Alias(ty::Projection, proj) = ty.kind()
|
||||
&& self.interner().def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& self.interner().is_impl_trait_in_trait(proj.def_id)
|
||||
{
|
||||
if let Some((ty, _)) = self.types.get(&proj.def_id) {
|
||||
return *ty;
|
||||
|
@ -1995,13 +1995,20 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
let infcx = tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let impl_ty_span = match tcx.hir().get_by_def_id(impl_ty_def_id) {
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(_, Some(ty)),
|
||||
..
|
||||
}) => ty.span,
|
||||
hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span,
|
||||
_ => bug!(),
|
||||
// A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the
|
||||
// span for an impl's associated type. Instead, for these, use the def_span for the synthesized
|
||||
// associated type.
|
||||
let impl_ty_span = if tcx.opt_rpitit_info(impl_ty.def_id).is_some() {
|
||||
tcx.def_span(impl_ty_def_id)
|
||||
} else {
|
||||
match tcx.hir().get_by_def_id(impl_ty_def_id) {
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(_, Some(ty)),
|
||||
..
|
||||
}) => ty.span,
|
||||
hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Type(ty), .. }) => ty.span,
|
||||
_ => bug!(),
|
||||
}
|
||||
};
|
||||
let assumed_wf_types = ocx.assumed_wf_types(param_env, impl_ty_span, impl_ty_def_id);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::astconv::AstConv;
|
|||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
|
||||
|
@ -58,17 +58,10 @@ fn opaque_type_bounds<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
opaque_def_id: DefId,
|
||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
item_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
in_trait: bool,
|
||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
||||
ty::print::with_no_queries!({
|
||||
let substs = InternalSubsts::identity_for_item(tcx, opaque_def_id);
|
||||
let item_ty = if in_trait {
|
||||
tcx.mk_projection(opaque_def_id, substs)
|
||||
} else {
|
||||
tcx.mk_opaque(opaque_def_id, substs)
|
||||
};
|
||||
|
||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||
let mut bounds = icx.astconv().compute_bounds(item_ty, ast_bounds);
|
||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||
|
@ -83,7 +76,18 @@ pub(super) fn explicit_item_bounds(
|
|||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> &'_ [(ty::Predicate<'_>, Span)] {
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||
// If the def_id is about an RPITIT, delegate explicit_item_bounds to the opaque_def_id that
|
||||
// generated the synthesized associate type.
|
||||
let rpitit_info = if let Some(ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
|
||||
tcx.opt_rpitit_info(def_id)
|
||||
{
|
||||
Some(opaque_def_id)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let bounds_def_id = rpitit_info.unwrap_or(def_id);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(bounds_def_id.expect_local());
|
||||
match tcx.hir().get(hir_id) {
|
||||
hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Type(bounds, _),
|
||||
|
@ -94,7 +98,15 @@ pub(super) fn explicit_item_bounds(
|
|||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
|
||||
span,
|
||||
..
|
||||
}) => opaque_type_bounds(tcx, def_id, bounds, *span, *in_trait),
|
||||
}) => {
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
let item_ty = if *in_trait || rpitit_info.is_some() {
|
||||
tcx.mk_projection(def_id, substs)
|
||||
} else {
|
||||
tcx.mk_opaque(def_id, substs)
|
||||
};
|
||||
opaque_type_bounds(tcx, bounds_def_id, bounds, item_ty, *span)
|
||||
}
|
||||
_ => bug!("item_bounds called on {:?}", def_id),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ use rustc_middle::ty::print::with_forced_trimmed_paths;
|
|||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{
|
||||
self, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
|
||||
self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable,
|
||||
TypeVisitableExt,
|
||||
};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
@ -244,6 +245,24 @@ fn get_path_containing_arg_in_pat<'hir>(
|
|||
}
|
||||
|
||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>> {
|
||||
// If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
|
||||
// side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
|
||||
// associated type in the impl.
|
||||
if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) {
|
||||
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
|
||||
Ok(map) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]);
|
||||
}
|
||||
Err(_) => {
|
||||
return ty::EarlyBinder(tcx.ty_error_with_message(
|
||||
DUMMY_SP,
|
||||
"Could not collect return position impl trait in trait tys",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let def_id = def_id.expect_local();
|
||||
use rustc_hir::*;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue