Rollup merge of #127439 - compiler-errors:uplift-elaborate, r=lcnr
Uplift elaboration into `rustc_type_ir` Allows us to deduplicate and consolidate elaboration (including these stupid elaboration duplicate fns i added for pretty printing like 3 years ago) so I'm pretty hyped about this change :3 r? lcnr
This commit is contained in:
commit
ffb93361b4
29 changed files with 506 additions and 522 deletions
|
@ -7,7 +7,6 @@ pub mod select;
|
|||
pub mod solve;
|
||||
pub mod specialization_graph;
|
||||
mod structural_impls;
|
||||
pub mod util;
|
||||
|
||||
use crate::mir::ConstraintCategory;
|
||||
use crate::ty::abstract_const::NotConstEvaluatable;
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
use crate::ty::{Clause, PolyTraitRef, ToPolyTraitRef, TyCtxt, Upcast};
|
||||
|
||||
/// Given a [`PolyTraitRef`], get the [`Clause`]s implied by the trait's definition.
|
||||
///
|
||||
/// This only exists in `rustc_middle` because the more powerful elaborator depends on
|
||||
/// `rustc_infer` for elaborating outlives bounds -- this should only be used for pretty
|
||||
/// printing.
|
||||
pub fn super_predicates_for_pretty_printing<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: PolyTraitRef<'tcx>,
|
||||
) -> impl Iterator<Item = Clause<'tcx>> {
|
||||
let clause = trait_ref.upcast(tcx);
|
||||
Elaborator { tcx, visited: FxHashSet::from_iter([clause]), stack: vec![clause] }
|
||||
}
|
||||
|
||||
/// Like [`super_predicates_for_pretty_printing`], except it only returns traits and filters out
|
||||
/// all other [`Clause`]s.
|
||||
pub fn supertraits_for_pretty_printing<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: PolyTraitRef<'tcx>,
|
||||
) -> impl Iterator<Item = PolyTraitRef<'tcx>> {
|
||||
super_predicates_for_pretty_printing(tcx, trait_ref).filter_map(|clause| {
|
||||
clause.as_trait_clause().map(|trait_clause| trait_clause.to_poly_trait_ref())
|
||||
})
|
||||
}
|
||||
|
||||
struct Elaborator<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
visited: FxHashSet<Clause<'tcx>>,
|
||||
stack: Vec<Clause<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> Elaborator<'tcx> {
|
||||
fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
|
||||
let super_predicates =
|
||||
self.tcx.explicit_super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|
||||
|&(pred, _)| {
|
||||
let clause = pred.instantiate_supertrait(self.tcx, trait_ref);
|
||||
self.visited.insert(clause).then_some(clause)
|
||||
},
|
||||
);
|
||||
|
||||
self.stack.extend(super_predicates);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Iterator for Elaborator<'tcx> {
|
||||
type Item = Clause<'tcx>;
|
||||
|
||||
fn next(&mut self) -> Option<Clause<'tcx>> {
|
||||
if let Some(clause) = self.stack.pop() {
|
||||
if let Some(trait_clause) = clause.as_trait_clause() {
|
||||
self.elaborate(trait_clause.to_poly_trait_ref());
|
||||
}
|
||||
Some(clause)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
|||
use rustc_ast::{self as ast, attr};
|
||||
use rustc_data_structures::defer;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
||||
|
@ -347,12 +347,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
fn explicit_super_predicates_of(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
|
||||
ty::EarlyBinder::bind(self.explicit_super_predicates_of(def_id).instantiate_identity(self))
|
||||
}
|
||||
|
||||
fn explicit_implied_predicates_of(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
|
||||
ty::EarlyBinder::bind(
|
||||
self.explicit_super_predicates_of(def_id)
|
||||
.instantiate_identity(self)
|
||||
.predicates
|
||||
.into_iter(),
|
||||
self.explicit_implied_predicates_of(def_id).instantiate_identity(self),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -532,10 +536,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
self.trait_def(trait_def_id).implement_via_object
|
||||
}
|
||||
|
||||
fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> {
|
||||
self.supertrait_def_ids(trait_def_id)
|
||||
}
|
||||
|
||||
fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
|
||||
self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
|
||||
}
|
||||
|
@ -573,6 +573,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
) -> Ty<'tcx> {
|
||||
placeholder.find_const_ty_from_env(param_env)
|
||||
}
|
||||
|
||||
fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
binder: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
self.anonymize_bound_vars(binder)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! bidirectional_lang_item_map {
|
||||
|
@ -2492,25 +2499,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// to identify which traits may define a given associated type to help avoid cycle errors,
|
||||
/// and to make size estimates for vtable layout computation.
|
||||
pub fn supertrait_def_ids(self, trait_def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
|
||||
let mut set = FxHashSet::default();
|
||||
let mut stack = vec![trait_def_id];
|
||||
|
||||
set.insert(trait_def_id);
|
||||
|
||||
iter::from_fn(move || -> Option<DefId> {
|
||||
let trait_did = stack.pop()?;
|
||||
let generic_predicates = self.explicit_super_predicates_of(trait_did);
|
||||
|
||||
for (predicate, _) in generic_predicates.predicates {
|
||||
if let ty::ClauseKind::Trait(data) = predicate.kind().skip_binder() {
|
||||
if set.insert(data.def_id()) {
|
||||
stack.push(data.def_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(trait_did)
|
||||
})
|
||||
rustc_type_ir::elaborate::supertrait_def_ids(self, trait_def_id)
|
||||
}
|
||||
|
||||
/// Given a closure signature, returns an equivalent fn signature. Detuples
|
||||
|
|
84
compiler/rustc_middle/src/ty/elaborate_impl.rs
Normal file
84
compiler/rustc_middle/src/ty/elaborate_impl.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use rustc_span::Span;
|
||||
use rustc_type_ir::elaborate::Elaboratable;
|
||||
|
||||
use crate::ty::{self, TyCtxt};
|
||||
|
||||
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
|
||||
fn predicate(&self) -> ty::Predicate<'tcx> {
|
||||
self.as_predicate()
|
||||
}
|
||||
|
||||
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
|
||||
clause
|
||||
}
|
||||
|
||||
fn child_with_derived_cause(
|
||||
&self,
|
||||
clause: ty::Clause<'tcx>,
|
||||
_span: Span,
|
||||
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
_index: usize,
|
||||
) -> Self {
|
||||
clause
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
|
||||
fn predicate(&self) -> ty::Predicate<'tcx> {
|
||||
*self
|
||||
}
|
||||
|
||||
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
|
||||
clause.as_predicate()
|
||||
}
|
||||
|
||||
fn child_with_derived_cause(
|
||||
&self,
|
||||
clause: ty::Clause<'tcx>,
|
||||
_span: Span,
|
||||
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
_index: usize,
|
||||
) -> Self {
|
||||
clause.as_predicate()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for (ty::Predicate<'tcx>, Span) {
|
||||
fn predicate(&self) -> ty::Predicate<'tcx> {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
|
||||
(clause.as_predicate(), self.1)
|
||||
}
|
||||
|
||||
fn child_with_derived_cause(
|
||||
&self,
|
||||
clause: ty::Clause<'tcx>,
|
||||
_span: Span,
|
||||
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
_index: usize,
|
||||
) -> Self {
|
||||
(clause.as_predicate(), self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Elaboratable<TyCtxt<'tcx>> for (ty::Clause<'tcx>, Span) {
|
||||
fn predicate(&self) -> ty::Predicate<'tcx> {
|
||||
self.0.as_predicate()
|
||||
}
|
||||
|
||||
fn child(&self, clause: ty::Clause<'tcx>) -> Self {
|
||||
(clause, self.1)
|
||||
}
|
||||
|
||||
fn child_with_derived_cause(
|
||||
&self,
|
||||
clause: ty::Clause<'tcx>,
|
||||
_span: Span,
|
||||
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
_index: usize,
|
||||
) -> Self {
|
||||
(clause, self.1)
|
||||
}
|
||||
}
|
|
@ -394,7 +394,7 @@ impl<'tcx> GenericPredicates<'tcx> {
|
|||
}
|
||||
|
||||
pub fn instantiate_own_identity(&self) -> impl Iterator<Item = (Clause<'tcx>, Span)> {
|
||||
EarlyBinder::bind(self.predicates).instantiate_identity_iter_copied()
|
||||
EarlyBinder::bind(self.predicates).iter_identity_copied()
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, tcx))]
|
||||
|
|
|
@ -148,6 +148,7 @@ mod closure;
|
|||
mod consts;
|
||||
mod context;
|
||||
mod diagnostics;
|
||||
mod elaborate_impl;
|
||||
mod erase_regions;
|
||||
mod generic_args;
|
||||
mod generics;
|
||||
|
|
|
@ -46,6 +46,10 @@ pub struct Predicate<'tcx>(
|
|||
);
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Predicate<TyCtxt<'tcx>> for Predicate<'tcx> {
|
||||
fn as_clause(self) -> Option<ty::Clause<'tcx>> {
|
||||
self.as_clause()
|
||||
}
|
||||
|
||||
fn is_coinductive(self, interner: TyCtxt<'tcx>) -> bool {
|
||||
self.is_coinductive(interner)
|
||||
}
|
||||
|
@ -173,7 +177,11 @@ pub struct Clause<'tcx>(
|
|||
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
|
||||
);
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {}
|
||||
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
|
||||
fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
|
||||
self.instantiate_supertrait(tcx, trait_ref)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
|
||||
type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
|
||||
use crate::query::IntoQueryParam;
|
||||
use crate::query::Providers;
|
||||
use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing};
|
||||
use crate::ty::GenericArgKind;
|
||||
use crate::ty::{
|
||||
ConstInt, Expr, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
|
||||
|
@ -23,6 +22,7 @@ use rustc_span::symbol::{kw, Ident, Symbol};
|
|||
use rustc_span::FileNameDisplayPreference;
|
||||
use rustc_target::abi::Size;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_type_ir::{elaborate, Upcast as _};
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
@ -1255,14 +1255,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
entry.has_fn_once = true;
|
||||
return;
|
||||
} else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) {
|
||||
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
|
||||
let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
|
||||
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
|
||||
.unwrap();
|
||||
|
||||
fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
|
||||
return;
|
||||
} else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) {
|
||||
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
|
||||
let super_trait_ref = elaborate::supertraits(self.tcx(), trait_ref)
|
||||
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
|
||||
.unwrap();
|
||||
|
||||
|
@ -1343,10 +1343,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
let bound_principal_with_self = bound_principal
|
||||
.with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self);
|
||||
|
||||
let super_projections: Vec<_> =
|
||||
super_predicates_for_pretty_printing(cx.tcx(), bound_principal_with_self)
|
||||
.filter_map(|clause| clause.as_projection_clause())
|
||||
.collect();
|
||||
let clause: ty::Clause<'tcx> = bound_principal_with_self.upcast(cx.tcx());
|
||||
let super_projections: Vec<_> = elaborate::elaborate(cx.tcx(), [clause])
|
||||
.filter_only_self()
|
||||
.filter_map(|clause| clause.as_projection_clause())
|
||||
.collect();
|
||||
|
||||
let mut projections: Vec<_> = predicates
|
||||
.projection_bounds()
|
||||
|
|
|
@ -811,6 +811,14 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||
Ty::new_var(tcx, vid)
|
||||
}
|
||||
|
||||
fn new_param(tcx: TyCtxt<'tcx>, param: ty::ParamTy) -> Self {
|
||||
Ty::new_param(tcx, param.index, param.name)
|
||||
}
|
||||
|
||||
fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderType) -> Self {
|
||||
Ty::new_placeholder(tcx, placeholder)
|
||||
}
|
||||
|
||||
fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundTy) -> Self {
|
||||
Ty::new_bound(interner, debruijn, var)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue