Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPITITs are DefKind::Opaque with new lowering strategy #109405

Merged
merged 2 commits into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
}) = item.kind
{
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let opaque_identity_ty = if in_trait {
let opaque_identity_ty = if in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() {
tcx.mk_projection(def_id.to_def_id(), substs)
} else {
tcx.mk_opaque(def_id.to_def_id(), substs)
Expand Down Expand Up @@ -554,7 +554,15 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
check_union(tcx, id.owner_id.def_id);
}
DefKind::OpaqueTy => {
check_opaque(tcx, id);
let opaque = tcx.hir().expect_item(id.owner_id.def_id).expect_opaque_ty();
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = opaque.origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
// Skip opaques from RPIT in traits with no default body.
} else {
check_opaque(tcx, id);
}
}
DefKind::ImplTraitPlaceholder => {
let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id());
Expand Down
21 changes: 19 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,6 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
| DefKind::Const
| DefKind::Static(..)
| DefKind::TyAlias
| DefKind::OpaqueTy
| DefKind::ForeignTy
| DefKind::Impl { .. }
| DefKind::AssocFn
Expand All @@ -1027,6 +1026,18 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
| DefKind::AnonConst
| DefKind::InlineConst => true,

DefKind::OpaqueTy => {
let opaque = tcx.hir().expect_item(def_id).expect_opaque_ty();
if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = opaque.origin
&& let hir::Node::TraitItem(trait_item) = tcx.hir().get_by_def_id(fn_def_id)
&& let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
{
false
} else {
true
}
}

DefKind::ImplTraitPlaceholder => {
let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id());
let assoc_item = tcx.associated_item(parent_def_id);
Expand All @@ -1044,7 +1055,13 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
let assoc_item = tcx.associated_item(def_id);
match assoc_item.container {
ty::AssocItemContainer::ImplContainer => true,
ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) always encode RPITITs,
// since we need to be able to "project" from an RPITIT associated item
// to an opaque when installing the default projection predicates in
// default trait methods with RPITITs.
ty::AssocItemContainer::TraitContainer => {
assoc_item.defaultness(tcx).has_value() || assoc_item.opt_rpitit_info.is_some()
}
}
}
DefKind::TyParam => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl<'hir> Map<'hir> {
ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
ItemKind::Mod(..) => DefKind::Mod,
ItemKind::OpaqueTy(ref opaque) => {
if opaque.in_trait {
if opaque.in_trait && !self.tcx.lower_impl_trait_in_trait_to_assoc_ty() {
DefKind::ImplTraitPlaceholder
} else {
DefKind::OpaqueTy
Expand Down
24 changes: 13 additions & 11 deletions compiler/rustc_ty_utils/src/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,16 @@ fn associated_type_for_impl_trait_in_trait(
tcx: TyCtxt<'_>,
opaque_ty_def_id: LocalDefId,
) -> LocalDefId {
let fn_def_id = tcx.impl_trait_in_trait_parent_fn(opaque_ty_def_id.to_def_id());
let trait_def_id = tcx.parent(fn_def_id);
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) =
tcx.hir().expect_item(opaque_ty_def_id).expect_opaque_ty().origin
else {
bug!("expected opaque for {opaque_ty_def_id:?}");
};
let trait_def_id = tcx.local_parent(fn_def_id);
assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);

let span = tcx.def_span(opaque_ty_def_id);
let trait_assoc_ty =
tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, DefPathData::ImplTraitAssocTy);

let local_def_id = trait_assoc_ty.def_id();
let def_id = local_def_id.to_def_id();
Expand All @@ -282,7 +285,7 @@ fn associated_type_for_impl_trait_in_trait(
container: ty::TraitContainer,
fn_has_self_parameter: false,
opt_rpitit_info: Some(ImplTraitInTraitData::Trait {
fn_def_id,
fn_def_id: fn_def_id.to_def_id(),
opaque_def_id: opaque_ty_def_id.to_def_id(),
}),
});
Expand Down Expand Up @@ -324,7 +327,7 @@ fn associated_type_for_impl_trait_in_trait(
params.iter().map(|param| (param.def_id, param.index)).collect();

ty::Generics {
parent: Some(trait_def_id),
parent: Some(trait_def_id.to_def_id()),
parent_count,
params,
param_def_id_to_index,
Expand All @@ -335,7 +338,7 @@ fn associated_type_for_impl_trait_in_trait(

// There are no predicates for the synthesized associated type.
trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
parent: Some(trait_def_id),
parent: Some(trait_def_id.to_def_id()),
predicates: &[],
});

Expand All @@ -356,7 +359,6 @@ fn associated_type_for_impl_trait_in_impl(
impl_fn_def_id: LocalDefId,
) -> LocalDefId {
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
let impl_def_id = impl_local_def_id.to_def_id();

// FIXME fix the span, we probably want the def_id of the return type of the function
let span = tcx.def_span(impl_fn_def_id);
Expand Down Expand Up @@ -402,7 +404,7 @@ fn associated_type_for_impl_trait_in_impl(
let trait_assoc_parent_count = trait_assoc_generics.parent_count;
let mut params = trait_assoc_generics.params.clone();

let parent_generics = tcx.generics_of(impl_def_id);
let parent_generics = tcx.generics_of(impl_local_def_id.to_def_id());
let parent_count = parent_generics.parent_count + parent_generics.params.len();

for param in &mut params {
Expand All @@ -413,7 +415,7 @@ fn associated_type_for_impl_trait_in_impl(
params.iter().map(|param| (param.def_id, param.index)).collect();

ty::Generics {
parent: Some(impl_def_id),
parent: Some(impl_local_def_id.to_def_id()),
parent_count,
params,
param_def_id_to_index,
Expand All @@ -424,7 +426,7 @@ fn associated_type_for_impl_trait_in_impl(

// There are no predicates for the synthesized associated type.
impl_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
parent: Some(impl_def_id),
parent: Some(impl_local_def_id.to_def_id()),
predicates: &[],
});

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty

#![feature(return_position_impl_trait_in_trait)]

pub trait Foo {
Expand Down