Skip to content

Commit c4dd9a2

Browse files
committed
Introduce DefPathData::ImplTraitInTrait
1 parent 876f129 commit c4dd9a2

File tree

8 files changed

+72
-23
lines changed

8 files changed

+72
-23
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1472,7 +1472,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
14721472
DefPathData::ImplTrait,
14731473
),
14741474
hir::OpaqueTyOrigin::FnReturn(fn_def_id) => {
1475-
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait)
1475+
if in_trait {
1476+
self.create_def(
1477+
fn_def_id,
1478+
opaque_ty_node_id,
1479+
DefPathData::ImplTraitInTrait(fn_def_id.to_def_id(), None),
1480+
)
1481+
} else {
1482+
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait)
1483+
}
14761484
}
14771485
hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"),
14781486
};
@@ -1839,8 +1847,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18391847

18401848
let fn_def_id = self.local_def_id(fn_node_id);
18411849

1842-
let opaque_ty_def_id =
1843-
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait);
1850+
let opaque_ty_def_id = if in_trait {
1851+
self.create_def(
1852+
fn_def_id,
1853+
opaque_ty_node_id,
1854+
DefPathData::ImplTraitInTrait(fn_def_id.to_def_id(), None),
1855+
)
1856+
} else {
1857+
self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait)
1858+
};
18441859

18451860
// When we create the opaque type for this async fn, it is going to have
18461861
// to capture all the lifetimes involved in the signature (including in the

compiler/rustc_hir/src/definitions.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
//! expressions) that are mostly just leftovers.
66
77
pub use crate::def_id::DefPathHash;
8-
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
8+
use crate::def_id::{
9+
CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE,
10+
};
911
use crate::def_path_hash_map::DefPathHashMap;
1012

1113
use rustc_data_structures::fx::FxHashMap;
@@ -245,6 +247,17 @@ impl DefPath {
245247

246248
s
247249
}
250+
251+
pub fn get_impl_trait_in_trait_data(&self) -> Option<(DefId, Option<DefId>)> {
252+
if let Some(def_path_data) = self.data.last()
253+
&& let DefPathData::ImplTraitInTrait(fn_def_id, of_trait) =
254+
def_path_data.data
255+
{
256+
Some((fn_def_id, of_trait))
257+
} else {
258+
None
259+
}
260+
}
248261
}
249262

250263
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
@@ -281,6 +294,10 @@ pub enum DefPathData {
281294
AnonConst,
282295
/// An `impl Trait` type node.
283296
ImplTrait,
297+
/// An `impl Trait` type node inside a `trait` or inside an `impl` of a `trait`.
298+
/// On a `trait` the value is `(trait_fn_def_id, None)`.
299+
/// On an `impl` the value is `(impl_fn_def_id, Some(trait_rpit_def_id))`.
300+
ImplTraitInTrait(DefId, Option<DefId>),
284301
}
285302

286303
impl Definitions {
@@ -404,7 +421,7 @@ impl DefPathData {
404421
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name),
405422

406423
Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst
407-
| ImplTrait => None,
424+
| ImplTrait | ImplTraitInTrait(..) => None,
408425
}
409426
}
410427

@@ -424,6 +441,7 @@ impl DefPathData {
424441
Ctor => DefPathDataName::Anon { namespace: sym::constructor },
425442
AnonConst => DefPathDataName::Anon { namespace: sym::constant },
426443
ImplTrait => DefPathDataName::Anon { namespace: sym::opaque },
444+
ImplTraitInTrait(..) => DefPathDataName::Anon { namespace: sym::opaque },
427445
}
428446
}
429447
}

compiler/rustc_hir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![feature(associated_type_defaults)]
66
#![feature(closure_track_caller)]
77
#![feature(const_btree_len)]
8+
#![feature(let_chains)]
89
#![feature(min_specialization)]
910
#![feature(never_type)]
1011
#![feature(rustc_attrs)]

compiler/rustc_hir_analysis/src/check/check.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -564,14 +564,17 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
564564
check_opaque(tcx, id);
565565
}
566566
DefKind::ImplTraitPlaceholder => {
567-
let parent = tcx.impl_trait_in_trait_parent(id.owner_id.to_def_id());
568-
// Only check the validity of this opaque type if the function has a default body
569-
if let hir::Node::TraitItem(hir::TraitItem {
570-
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
571-
..
572-
}) = tcx.hir().get_by_def_id(parent.expect_local())
567+
if let Some((fn_def_id, _)) =
568+
tcx.def_path(id.owner_id.to_def_id()).get_impl_trait_in_trait_data()
573569
{
574-
check_opaque(tcx, id);
570+
// Only check the validity of this opaque type if the function has a default body
571+
if let hir::Node::TraitItem(hir::TraitItem {
572+
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
573+
..
574+
}) = tcx.hir().get_by_def_id(fn_def_id.as_local().unwrap())
575+
{
576+
check_opaque(tcx, id);
577+
}
575578
}
576579
}
577580
DefKind::TyAlias => {

compiler/rustc_metadata/src/rmeta/encoder.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -1020,15 +1020,20 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
10201020
| DefKind::InlineConst => true,
10211021

10221022
DefKind::ImplTraitPlaceholder => {
1023-
let parent_def_id = tcx.impl_trait_in_trait_parent(def_id.to_def_id());
1024-
let assoc_item = tcx.associated_item(parent_def_id);
1025-
match assoc_item.container {
1026-
// Always encode an RPIT in an impl fn, since it always has a body
1027-
ty::AssocItemContainer::ImplContainer => true,
1028-
ty::AssocItemContainer::TraitContainer => {
1029-
// Encode an RPIT for a trait only if the trait has a default body
1030-
assoc_item.defaultness(tcx).has_value()
1023+
if let Some((fn_def_id, _)) =
1024+
tcx.def_path(def_id.to_def_id()).get_impl_trait_in_trait_data()
1025+
{
1026+
let assoc_item = tcx.associated_item(fn_def_id);
1027+
match assoc_item.container {
1028+
// Always encode an RPIT in an impl fn, since it always has a body
1029+
ty::AssocItemContainer::ImplContainer => true,
1030+
ty::AssocItemContainer::TraitContainer => {
1031+
// Encode an RPIT for a trait only if the trait has a default body
1032+
assoc_item.defaultness(tcx).has_value()
1033+
}
10311034
}
1035+
} else {
1036+
bug!();
10321037
}
10331038
}
10341039

compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ fn encode_ty_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> String {
396396
hir::definitions::DefPathData::ClosureExpr => "C",
397397
hir::definitions::DefPathData::Ctor => "c",
398398
hir::definitions::DefPathData::AnonConst => "k",
399-
hir::definitions::DefPathData::ImplTrait => "i",
399+
hir::definitions::DefPathData::ImplTrait
400+
| hir::definitions::DefPathData::ImplTraitInTrait(..) => "i",
400401
hir::definitions::DefPathData::CrateRoot
401402
| hir::definitions::DefPathData::Use
402403
| hir::definitions::DefPathData::GlobalAsm

compiler/rustc_symbol_mangling/src/v0.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
782782
DefPathData::ClosureExpr => 'C',
783783
DefPathData::Ctor => 'c',
784784
DefPathData::AnonConst => 'k',
785-
DefPathData::ImplTrait => 'i',
785+
DefPathData::ImplTrait | DefPathData::ImplTraitInTrait(..) => 'i',
786786

787787
// These should never show up as `path_append` arguments.
788788
DefPathData::CrateRoot

compiler/rustc_trait_selection/src/traits/project.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,13 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
13241324
) {
13251325
let tcx = selcx.tcx();
13261326
if tcx.def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
1327-
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
1327+
let trait_fn_def_id = if let Some((fn_def_id, _)) =
1328+
tcx.def_path(obligation.predicate.item_def_id).get_impl_trait_in_trait_data()
1329+
{
1330+
fn_def_id
1331+
} else {
1332+
tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id)
1333+
};
13281334
// If we are trying to project an RPITIT with trait's default `Self` parameter,
13291335
// then we must be within a default trait body.
13301336
if obligation.predicate.self_ty()

0 commit comments

Comments
 (0)