Skip to content

Commit 4c1d7ca

Browse files
committed
Auto merge of #157194 - mu001999-contrib:type-dep-defs, r=<try>
Record type-dependent defs in item signatures
2 parents 0cf9681 + 0c620f0 commit 4c1d7ca

47 files changed

Lines changed: 717 additions & 172 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! At present, however, we do run collection across all items in the
1515
//! crate as a kind of pass. This should eventually be factored away.
1616
17-
use std::cell::Cell;
17+
use std::cell::{Cell, RefCell};
1818
use std::ops::ControlFlow;
1919
use std::{assert_matches, iter};
2020

@@ -27,7 +27,9 @@ use rustc_errors::{
2727
use rustc_hir::def::{DefKind, Res};
2828
use rustc_hir::def_id::{DefId, LocalDefId};
2929
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
30-
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr};
30+
use rustc_hir::{
31+
self as hir, GenericParamKind, HirId, ItemLocalMap, Node, PreciseCapturingArgKind, find_attr,
32+
};
3133
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3234
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
3335
use rustc_middle::hir::nested_filter;
@@ -63,30 +65,39 @@ pub(crate) fn provide(providers: &mut Providers) {
6365
resolve_bound_vars::provide(providers);
6466
*providers = Providers {
6567
type_of: type_of::type_of,
68+
type_of_with_type_dep_defs: type_of::type_of_with_type_dep_defs,
6669
type_of_opaque: type_of::type_of_opaque,
6770
type_of_opaque_hir_typeck: type_of::type_of_opaque_hir_typeck,
6871
type_alias_is_lazy: type_of::type_alias_is_lazy,
6972
item_bounds: item_bounds::item_bounds,
7073
explicit_item_bounds: item_bounds::explicit_item_bounds,
74+
explicit_item_bounds_with_type_dep_defs:
75+
item_bounds::explicit_item_bounds_with_type_dep_defs,
7176
item_self_bounds: item_bounds::item_self_bounds,
7277
explicit_item_self_bounds: item_bounds::explicit_item_self_bounds,
7378
item_non_self_bounds: item_bounds::item_non_self_bounds,
7479
impl_super_outlives: item_bounds::impl_super_outlives,
7580
generics_of: generics_of::generics_of,
7681
predicates_of: predicates_of::predicates_of,
7782
explicit_predicates_of: predicates_of::explicit_predicates_of,
83+
explicit_predicates_of_with_type_dep_defs:
84+
predicates_of::explicit_predicates_of_with_type_dep_defs,
7885
explicit_super_predicates_of: predicates_of::explicit_super_predicates_of,
7986
explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of,
8087
explicit_supertraits_containing_assoc_item:
8188
predicates_of::explicit_supertraits_containing_assoc_item,
8289
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
90+
trait_explicit_predicates_and_bounds_with_type_dep_defs:
91+
predicates_of::trait_explicit_predicates_and_bounds_with_type_dep_defs,
8392
const_conditions: predicates_of::const_conditions,
8493
explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds,
8594
type_param_predicates: predicates_of::type_param_predicates,
8695
trait_def,
8796
adt_def,
8897
fn_sig,
98+
fn_sig_with_type_dep_defs,
8999
impl_trait_header,
100+
impl_trait_header_with_type_dep_defs,
90101
coroutine_kind,
91102
coroutine_for_closure,
92103
opaque_ty_origin,
@@ -132,6 +143,7 @@ pub(crate) struct ItemCtxt<'tcx> {
132143
item_def_id: LocalDefId,
133144
tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
134145
lowering_delegation_segment: bool,
146+
type_dependent_defs: RefCell<ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>>>,
135147
}
136148

137149
///////////////////////////////////////////////////////////////////////////
@@ -255,6 +267,7 @@ impl<'tcx> ItemCtxt<'tcx> {
255267
item_def_id,
256268
tainted_by_errors: Cell::new(None),
257269
lowering_delegation_segment: delegation,
270+
type_dependent_defs: Default::default(),
258271
}
259272
}
260273

@@ -274,6 +287,10 @@ impl<'tcx> ItemCtxt<'tcx> {
274287
self.tcx.hir_node(self.hir_id())
275288
}
276289

290+
fn take_type_dependent_defs(&self) -> ItemLocalMap<Result<(DefKind, DefId), ErrorGuaranteed>> {
291+
self.type_dependent_defs.take()
292+
}
293+
277294
fn check_tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
278295
match self.tainted_by_errors.get() {
279296
Some(err) => Err(err),
@@ -538,7 +555,11 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
538555
}
539556

540557
fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
541-
// There's no place to record types from signatures?
558+
// There's no place to record types from signatures.
559+
}
560+
561+
fn record_res(&self, hir: HirId, res: Result<(DefKind, DefId), ErrorGuaranteed>) {
562+
self.type_dependent_defs.borrow_mut().insert(hir.local_id, res);
542563
}
543564

544565
fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
@@ -1003,6 +1024,14 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
10031024

10041025
#[instrument(level = "debug", skip(tcx), ret)]
10051026
fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
1027+
tcx.fn_sig_with_type_dep_defs(def_id).0
1028+
}
1029+
1030+
#[instrument(level = "debug", skip(tcx), ret)]
1031+
fn fn_sig_with_type_dep_defs(
1032+
tcx: TyCtxt<'_>,
1033+
def_id: LocalDefId,
1034+
) -> (ty::EarlyBinder<'_, ty::PolyFnSig<'_>>, &'_ ty::TypeDepDefs) {
10061035
use rustc_hir::Node::*;
10071036
use rustc_hir::*;
10081037

@@ -1053,7 +1082,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
10531082

10541083
ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
10551084
let abi = tcx.hir_get_foreign_abi(hir_id);
1056-
compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
1085+
compute_sig_of_foreign_fn_decl(&icx, sig.decl, abi, sig.header.safety())
10571086
}
10581087

10591088
Ctor(data) => {
@@ -1085,7 +1114,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
10851114
bug!("unexpected sort of node in fn_sig(): {:?}", x);
10861115
}
10871116
};
1088-
ty::EarlyBinder::bind(output)
1117+
(
1118+
ty::EarlyBinder::bind(output),
1119+
tcx.arena.alloc(ty::TypeDepDefs {
1120+
hir_owner: hir_id.owner,
1121+
type_dependent_defs: icx.take_type_dependent_defs(),
1122+
}),
1123+
)
10891124
}
10901125

10911126
fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
@@ -1390,8 +1425,12 @@ pub fn suggest_impl_trait<'tcx>(
13901425
None
13911426
}
13921427

1393-
fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader<'_> {
1428+
fn impl_trait_header_with_type_dep_defs(
1429+
tcx: TyCtxt<'_>,
1430+
def_id: LocalDefId,
1431+
) -> (ty::ImplTraitHeader<'_>, &'_ ty::TypeDepDefs) {
13941432
let icx = ItemCtxt::new(tcx, def_id);
1433+
let hir_owner = icx.hir_id().owner;
13951434
let item = tcx.hir_expect_item(def_id);
13961435
let impl_ = item.expect_impl();
13971436
let of_trait = impl_
@@ -1404,12 +1443,24 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader
14041443

14051444
let trait_ref = icx.lowerer().lower_impl_trait_ref(&of_trait.trait_ref, selfty);
14061445

1407-
ty::ImplTraitHeader {
1446+
let header = ty::ImplTraitHeader {
14081447
trait_ref: ty::EarlyBinder::bind(trait_ref),
14091448
safety: of_trait.safety,
14101449
polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation),
14111450
constness: impl_.constness,
1412-
}
1451+
};
1452+
1453+
(
1454+
header,
1455+
tcx.arena.alloc(ty::TypeDepDefs {
1456+
hir_owner,
1457+
type_dependent_defs: icx.take_type_dependent_defs(),
1458+
}),
1459+
)
1460+
}
1461+
1462+
fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader<'_> {
1463+
tcx.impl_trait_header_with_type_dep_defs(def_id).0
14131464
}
14141465

14151466
fn check_impl_constness(
@@ -1493,15 +1544,15 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
14931544
}
14941545

14951546
fn compute_sig_of_foreign_fn_decl<'tcx>(
1496-
tcx: TyCtxt<'tcx>,
1497-
def_id: LocalDefId,
1547+
icx: &ItemCtxt<'tcx>,
14981548
decl: &'tcx hir::FnDecl<'tcx>,
14991549
abi: ExternAbi,
15001550
safety: hir::Safety,
15011551
) -> ty::PolyFnSig<'tcx> {
1552+
let tcx = icx.tcx();
1553+
let def_id = icx.item_def_id;
15021554
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1503-
let fty =
1504-
ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
1555+
let fty = icx.lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
15051556

15061557
// Feature gate SIMD types in FFI, since I am not sure that the
15071558
// ABIs are handled at all correctly. -huonw

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ fn associated_type_bounds<'tcx>(
2929
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
3030
span: Span,
3131
filter: PredicateFilter,
32+
icx: &ItemCtxt<'tcx>,
3233
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
3334
ty::print::with_reduced_queries!({
3435
let item_ty = Ty::new_projection_from_args(
@@ -37,7 +38,6 @@ fn associated_type_bounds<'tcx>(
3738
GenericArgs::identity_for_item(tcx, assoc_item_def_id),
3839
);
3940

40-
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
4141
let mut bounds = Vec::new();
4242
icx.lowerer().lower_bounds(
4343
item_ty,
@@ -354,17 +354,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
354354
/// impl trait it isn't possible to write a suitable predicate on the
355355
/// containing function and for type-alias impl trait we don't have a backwards
356356
/// compatibility issue.
357-
#[instrument(level = "trace", skip(tcx, item_ty))]
357+
#[instrument(level = "trace", skip(tcx, item_ty, icx))]
358358
fn opaque_type_bounds<'tcx>(
359359
tcx: TyCtxt<'tcx>,
360-
opaque_def_id: LocalDefId,
361360
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
362361
item_ty: Ty<'tcx>,
363362
span: Span,
364363
filter: PredicateFilter,
364+
icx: &ItemCtxt<'tcx>,
365365
) -> &'tcx [(ty::Clause<'tcx>, Span)] {
366366
ty::print::with_reduced_queries!({
367-
let icx = ItemCtxt::new(tcx, opaque_def_id);
368367
let mut bounds = Vec::new();
369368
icx.lowerer().lower_bounds(
370369
item_ty,
@@ -408,28 +407,46 @@ pub(super) fn explicit_item_bounds(
408407
tcx: TyCtxt<'_>,
409408
def_id: LocalDefId,
410409
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
411-
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All)
410+
tcx.explicit_item_bounds_with_type_dep_defs(def_id).0
411+
}
412+
413+
pub(super) fn explicit_item_bounds_with_type_dep_defs(
414+
tcx: TyCtxt<'_>,
415+
def_id: LocalDefId,
416+
) -> (ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]>, &'_ ty::TypeDepDefs) {
417+
let hir_id = tcx.local_def_id_to_hir_id(def_id);
418+
let icx = ItemCtxt::new(tcx, def_id);
419+
let bounds = explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::All, &icx);
420+
(
421+
bounds,
422+
tcx.arena.alloc(ty::TypeDepDefs {
423+
hir_owner: hir_id.owner,
424+
type_dependent_defs: icx.take_type_dependent_defs(),
425+
}),
426+
)
412427
}
413428

414429
pub(super) fn explicit_item_self_bounds(
415430
tcx: TyCtxt<'_>,
416431
def_id: LocalDefId,
417432
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
418-
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly)
433+
let icx = ItemCtxt::new(tcx, def_id);
434+
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::SelfOnly, &icx)
419435
}
420436

421-
pub(super) fn explicit_item_bounds_with_filter(
422-
tcx: TyCtxt<'_>,
437+
pub(super) fn explicit_item_bounds_with_filter<'tcx>(
438+
tcx: TyCtxt<'tcx>,
423439
def_id: LocalDefId,
424440
filter: PredicateFilter,
425-
) -> ty::EarlyBinder<'_, &'_ [(ty::Clause<'_>, Span)]> {
441+
icx: &ItemCtxt<'tcx>,
442+
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
426443
match tcx.opt_rpitit_info(def_id.to_def_id()) {
427444
// RPITIT's bounds are the same as opaque type bounds, but with
428445
// a projection self type.
429446
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
430447
let opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
431448
let bounds =
432-
associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter);
449+
associated_type_bounds(tcx, def_id, opaque_ty.bounds, opaque_ty.span, filter, icx);
433450
return ty::EarlyBinder::bind(bounds);
434451
}
435452
Some(ty::ImplTraitInTraitData::Impl { .. }) => {
@@ -443,7 +460,7 @@ pub(super) fn explicit_item_bounds_with_filter(
443460
kind: hir::TraitItemKind::Type(bounds, _),
444461
span,
445462
..
446-
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
463+
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter, icx),
447464
hir::Node::OpaqueTy(hir::OpaqueTy { bounds, origin, span, .. }) => match origin {
448465
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`,
449466
// when we're asking for the item bounds of the *opaques* in a trait's default
@@ -459,7 +476,7 @@ pub(super) fn explicit_item_bounds_with_filter(
459476
let args = GenericArgs::identity_for_item(tcx, def_id);
460477
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
461478
let bounds = &*tcx.arena.alloc_slice(
462-
&opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter)
479+
&opaque_type_bounds(tcx, bounds, item_ty, *span, filter, icx)
463480
.to_vec()
464481
.fold_with(&mut AssocTyToOpaque { tcx, fn_def_id: parent.to_def_id() }),
465482
);
@@ -477,7 +494,7 @@ pub(super) fn explicit_item_bounds_with_filter(
477494
| rustc_hir::OpaqueTyOrigin::TyAlias { parent: _, .. } => {
478495
let args = GenericArgs::identity_for_item(tcx, def_id);
479496
let item_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
480-
let bounds = opaque_type_bounds(tcx, def_id, bounds, item_ty, *span, filter);
497+
let bounds = opaque_type_bounds(tcx, bounds, item_ty, *span, filter, icx);
481498
assert_only_contains_predicates_from(filter, bounds, item_ty);
482499
bounds
483500
}

0 commit comments

Comments
 (0)