Skip to content

Commit

Permalink
Uplift binder
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed May 20, 2024
1 parent 9fa07a4 commit 633a0c6
Show file tree
Hide file tree
Showing 23 changed files with 685 additions and 651 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::FnSig<I> {
}
}

impl<I: rustc_type_ir::Interner, T> IntoDiagArg for rustc_type_ir::Binder<I, T>
where
T: IntoDiagArg,
{
fn into_diag_arg(self) -> DiagArgValue {
self.skip_binder().into_diag_arg()
}
}

into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);

impl IntoDiagArg for bool {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_infer::traits::FulfillmentError;
use rustc_middle::bug;
use rustc_middle::query::Key;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{self, suggest_constraining_type_param};
use rustc_middle::ty::{AdtDef, Ty, TyCtxt, TypeVisitableExt};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
use rustc_middle::ty::{
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
TypeVisitableExt,
Expand Down
58 changes: 7 additions & 51 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,11 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for Ty<'tcx> {
}
}

impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E>
for ty::Binder<'tcx, ty::PredicateKind<'tcx>>
{
fn encode(&self, e: &mut E) {
self.bound_vars().encode(e);
encode_with_shorthand(e, &self.skip_binder(), TyEncoder::predicate_shorthands);
}
}

impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Predicate<'tcx> {
fn encode(&self, e: &mut E) {
self.kind().encode(e);
let kind = self.kind();
kind.bound_vars().encode(e);
encode_with_shorthand(e, &kind.skip_binder(), TyEncoder::predicate_shorthands);
}
}

Expand Down Expand Up @@ -233,13 +226,11 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Ty<'tcx> {
}
}

impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D>
for ty::Binder<'tcx, ty::PredicateKind<'tcx>>
{
fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Predicate<'tcx> {
fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
let bound_vars = Decodable::decode(decoder);
// Handle shorthands first, if we have a usize > 0x80.
ty::Binder::bind_with_vars(
let predicate_kind = ty::Binder::bind_with_vars(
if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize();
assert!(pos >= SHORTHAND_OFFSET);
Expand All @@ -250,13 +241,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D>
<ty::PredicateKind<'tcx> as Decodable<D>>::decode(decoder)
},
bound_vars,
)
}
}

impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Predicate<'tcx> {
fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
let predicate_kind = Decodable::decode(decoder);
);
decoder.interner().mk_predicate(predicate_kind)
}
}
Expand Down Expand Up @@ -599,32 +584,3 @@ macro_rules! implement_ty_decoder {
}
}
}

macro_rules! impl_binder_encode_decode {
($($t:ty),+ $(,)?) => {
$(
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::Binder<'tcx, $t> {
fn encode(&self, e: &mut E) {
self.bound_vars().encode(e);
self.as_ref().skip_binder().encode(e);
}
}
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Binder<'tcx, $t> {
fn decode(decoder: &mut D) -> Self {
let bound_vars = Decodable::decode(decoder);
ty::Binder::bind_with_vars(Decodable::decode(decoder), bound_vars)
}
}
)*
}
}

impl_binder_encode_decode! {
&'tcx ty::List<Ty<'tcx>>,
ty::FnSig<'tcx>,
ty::Predicate<'tcx>,
ty::TraitPredicate<'tcx>,
ty::ExistentialPredicate<'tcx>,
ty::TraitRef<'tcx>,
ty::ExistentialTraitRef<'tcx>,
}
11 changes: 7 additions & 4 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData,
GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern,
PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicatePolarity,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, TypeVisitable,
Visibility,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, Visibility,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
Expand Down Expand Up @@ -96,9 +95,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type GenericArg = ty::GenericArg<'tcx>;
type Term = ty::Term<'tcx>;

type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
type BoundVars = &'tcx List<ty::BoundVariableKind>;
type BoundVar = ty::BoundVariableKind;
type BoundVarKind = ty::BoundVariableKind;

type CanonicalVars = CanonicalVarInfos<'tcx>;
type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
Expand Down Expand Up @@ -138,6 +136,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {

type ParamEnv = ty::ParamEnv<'tcx>;
type Predicate = Predicate<'tcx>;
type Clause = Clause<'tcx>;
type TraitPredicate = ty::TraitPredicate<'tcx>;
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
Expand Down Expand Up @@ -245,6 +244,10 @@ impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
}

impl<'tcx> rustc_type_ir::inherent::Safety<TyCtxt<'tcx>> for hir::Safety {
fn is_safe(self) -> bool {
matches!(self, hir::Safety::Safe)
}

fn prefix_str(self) -> &'static str {
self.prefix_str()
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/ty/generic_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
GenericArgs::identity_for_item(tcx, def_id)
}

fn extend_with_error(
tcx: TyCtxt<'tcx>,
def_id: DefId,
original_args: &[ty::GenericArg<'tcx>],
) -> ty::GenericArgsRef<'tcx> {
ty::GenericArgs::extend_with_error(tcx, def_id, original_args)
}
}

impl<'tcx> rustc_type_ir::inherent::IntoKind for GenericArg<'tcx> {
Expand Down
127 changes: 4 additions & 123 deletions compiler/rustc_middle/src/ty/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use rustc_type_ir as ir;
use std::cmp::Ordering;

use crate::ty::{
self, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags,
Upcast, UpcastFrom, WithCachedTypeInfo,
self, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Ty, TyCtxt, TypeFlags, Upcast,
UpcastFrom, WithCachedTypeInfo,
};

pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
Expand Down Expand Up @@ -155,6 +155,8 @@ 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> Clause<'tcx> {
pub fn as_predicate(self) -> Predicate<'tcx> {
Predicate(self.0)
Expand Down Expand Up @@ -231,34 +233,6 @@ impl<'tcx> ExistentialPredicate<'tcx> {

pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;

impl<'tcx> PolyExistentialPredicate<'tcx> {
/// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`),
/// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self`
/// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example).
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Clause<'tcx> {
match self.skip_binder() {
ExistentialPredicate::Trait(tr) => {
self.rebind(tr).with_self_ty(tcx, self_ty).upcast(tcx)
}
ExistentialPredicate::Projection(p) => {
self.rebind(p.with_self_ty(tcx, self_ty)).upcast(tcx)
}
ExistentialPredicate::AutoTrait(did) => {
let generics = tcx.generics_of(did);
let trait_ref = if generics.own_params.len() == 1 {
ty::TraitRef::new(tcx, did, [self_ty])
} else {
// If this is an ill-formed auto trait, then synthesize
// new error args for the missing generics.
let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]);
ty::TraitRef::new(tcx, did, err_args)
};
self.rebind(trait_ref).upcast(tcx)
}
}
}
}

impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
/// Returns the "principal `DefId`" of this set of existential predicates.
///
Expand Down Expand Up @@ -322,49 +296,9 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
}

pub type PolyTraitRef<'tcx> = ty::Binder<'tcx, TraitRef<'tcx>>;

impl<'tcx> PolyTraitRef<'tcx> {
pub fn self_ty(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
self.map_bound_ref(|tr| tr.self_ty())
}

pub fn def_id(&self) -> DefId {
self.skip_binder().def_id
}
}

pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>;

impl<'tcx> PolyExistentialTraitRef<'tcx> {
pub fn def_id(&self) -> DefId {
self.skip_binder().def_id
}

/// Object types don't have a self type specified. Therefore, when
/// we convert the principal trait-ref into a normal trait-ref,
/// you must give *some* self type. A common choice is `mk_err()`
/// or some placeholder type.
pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
}
}

pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>;

impl<'tcx> PolyExistentialProjection<'tcx> {
pub fn with_self_ty(
&self,
tcx: TyCtxt<'tcx>,
self_ty: Ty<'tcx>,
) -> ty::PolyProjectionPredicate<'tcx> {
self.map_bound(|p| p.with_self_ty(tcx, self_ty))
}

pub fn item_def_id(&self) -> DefId {
self.skip_binder().def_id
}
}

impl<'tcx> Clause<'tcx> {
/// Performs a instantiation suitable for going from a
/// poly-trait-ref to supertraits that must hold if that
Expand Down Expand Up @@ -473,22 +407,6 @@ impl<'tcx> Clause<'tcx> {

pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;

impl<'tcx> PolyTraitPredicate<'tcx> {
pub fn def_id(self) -> DefId {
// Ok to skip binder since trait `DefId` does not care about regions.
self.skip_binder().def_id()
}

pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> {
self.map_bound(|trait_ref| trait_ref.self_ty())
}

#[inline]
pub fn polarity(self) -> PredicatePolarity {
self.skip_binder().polarity
}
}

/// `A: B`
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
Expand All @@ -497,47 +415,10 @@ pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty:
pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>;
pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>;

pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>;

pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;

pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>;

impl<'tcx> PolyProjectionPredicate<'tcx> {
/// Returns the `DefId` of the trait of the associated item being projected.
#[inline]
pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
self.skip_binder().projection_term.trait_def_id(tcx)
}

/// Get the [PolyTraitRef] required for this projection to be well formed.
/// Note that for generic associated types the predicates of the associated
/// type also need to be checked.
#[inline]
pub fn required_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'tcx> {
// Note: unlike with `TraitRef::to_poly_trait_ref()`,
// `self.0.trait_ref` is permitted to have escaping regions.
// This is because here `self` has a `Binder` and so does our
// return value, so we are preserving the number of binding
// levels.
self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx))
}

pub fn term(&self) -> Binder<'tcx, Term<'tcx>> {
self.map_bound(|predicate| predicate.term)
}

/// The `DefId` of the `TraitItem` for the associated type.
///
/// Note that this is not the `DefId` of the `TraitRef` containing this
/// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
pub fn projection_def_id(&self) -> DefId {
// Ok to skip binder since trait `DefId` does not care about regions.
self.skip_binder().projection_term.def_id
}
}

pub trait ToPolyTraitRef<'tcx> {
fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>;
}
Expand Down
19 changes: 5 additions & 14 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2934,12 +2934,13 @@ impl<'tcx> ty::TraitRef<'tcx> {
}
}

#[extension(pub trait PrintPolyTraitRefExt<'tcx>)]
impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> {
pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> {
fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> {
self.map_bound(|tr| tr.print_only_trait_path())
}

pub fn print_trait_sugared(self) -> ty::Binder<'tcx, TraitRefPrintSugared<'tcx>> {
fn print_trait_sugared(self) -> ty::Binder<'tcx, TraitRefPrintSugared<'tcx>> {
self.map_bound(|tr| tr.print_trait_sugared())
}
}
Expand All @@ -2960,8 +2961,9 @@ impl<'tcx> ty::TraitPredicate<'tcx> {
}
}

#[extension(pub trait PrintPolyTraitPredicateExt<'tcx>)]
impl<'tcx> ty::PolyTraitPredicate<'tcx> {
pub fn print_modifiers_and_trait_path(
fn print_modifiers_and_trait_path(
self,
) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> {
self.map_bound(TraitPredPrintModifiersAndPath)
Expand Down Expand Up @@ -3016,17 +3018,6 @@ forward_display_to_print! {
&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
ty::Const<'tcx>,

// HACK(eddyb) these are exhaustive instead of generic,
// because `for<'tcx>` isn't possible yet.
ty::PolyExistentialProjection<'tcx>,
ty::PolyExistentialTraitRef<'tcx>,
ty::Binder<'tcx, ty::TraitRef<'tcx>>,
ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
ty::Binder<'tcx, TraitRefPrintSugared<'tcx>>,
ty::Binder<'tcx, ty::FnSig<'tcx>>,
ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>>,
ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>,
ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
}
Expand Down
Loading

0 comments on commit 633a0c6

Please sign in to comment.