Skip to content

Commit

Permalink
Uplift AliasTy
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed May 14, 2024
1 parent 3458211 commit 1ad28a6
Show file tree
Hide file tree
Showing 15 changed files with 584 additions and 534 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::ExistentialTrait
}
}

impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst<I> {
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
format!("{self:?}").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
18 changes: 15 additions & 3 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_type_ir::ConstKind as IrConstKind;
use rustc_type_ir::{TypeFlags, WithCachedTypeInfo};
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};

mod int;
mod kind;
Expand All @@ -20,7 +19,8 @@ use rustc_span::Span;
use rustc_span::DUMMY_SP;
pub use valtree::*;

pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;

#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
Expand Down Expand Up @@ -184,9 +184,21 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
Const::new_bound(tcx, debruijn, var, ty)
}

fn new_unevaluated(
interner: TyCtxt<'tcx>,
uv: ty::UnevaluatedConst<'tcx>,
ty: Ty<'tcx>,
) -> Self {
Const::new_unevaluated(interner, uv, ty)
}

fn ty(self) -> Ty<'tcx> {
self.ty()
}

fn into_term(self) -> ty::Term<'tcx> {
self.into()
}
}

impl<'tcx> Const<'tcx> {
Expand Down
30 changes: 4 additions & 26 deletions compiler/rustc_middle/src/ty/consts/kind.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
use super::Const;
use crate::mir;
use crate::ty::abstract_const::CastKind;
use crate::ty::GenericArgsRef;
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
use rustc_hir::def_id::DefId;
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};

/// An unevaluated (potentially generic) constant used in the type-system.
#[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct UnevaluatedConst<'tcx> {
pub def: DefId,
pub args: GenericArgsRef<'tcx>,
}

impl rustc_errors::IntoDiagArg for UnevaluatedConst<'_> {
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
format!("{self:?}").into_diag_arg()
}
}

impl<'tcx> UnevaluatedConst<'tcx> {
#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)]
impl<'tcx> ty::UnevaluatedConst<'tcx> {
/// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this
/// hurts performance.
#[inline]
pub(crate) fn prepare_for_eval(
fn prepare_for_eval(
self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -55,13 +40,6 @@ impl<'tcx> UnevaluatedConst<'tcx> {
}
}

impl<'tcx> UnevaluatedConst<'tcx> {
#[inline]
pub fn new(def: DefId, args: GenericArgsRef<'tcx>) -> UnevaluatedConst<'tcx> {
UnevaluatedConst { def, args }
}
}

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
pub enum Expr<'tcx> {
Expand Down
76 changes: 67 additions & 9 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ use rustc_type_ir::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};

use std::assert_matches::assert_matches;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt;
Expand All @@ -91,67 +92,124 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
type AdtDef = ty::AdtDef<'tcx>;
type GenericArgs = ty::GenericArgsRef<'tcx>;
type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
type GenericArg = ty::GenericArg<'tcx>;
type Term = ty::Term<'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 CanonicalVars = CanonicalVarInfos<'tcx>;

type CanonicalVars = CanonicalVarInfos<'tcx>;
type Ty = Ty<'tcx>;
type Tys = &'tcx List<Ty<'tcx>>;
type AliasTy = ty::AliasTy<'tcx>;
type ParamTy = ParamTy;
type BoundTy = ty::BoundTy;
type PlaceholderTy = ty::PlaceholderType;
type ErrorGuaranteed = ErrorGuaranteed;

type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
type PolyFnSig = PolyFnSig<'tcx>;
type AllocId = crate::mir::interpret::AllocId;
type Pat = Pattern<'tcx>;

type Pat = Pattern<'tcx>;
type Const = ty::Const<'tcx>;
type AliasConst = ty::UnevaluatedConst<'tcx>;
type PlaceholderConst = ty::PlaceholderConst;
type ParamConst = ty::ParamConst;
type BoundConst = ty::BoundVar;
type ValueConst = ty::ValTree<'tcx>;
type ExprConst = ty::Expr<'tcx>;

type ExprConst = ty::Expr<'tcx>;
type Region = Region<'tcx>;
type EarlyParamRegion = ty::EarlyParamRegion;
type LateParamRegion = ty::LateParamRegion;
type BoundRegion = ty::BoundRegion;
type InferRegion = ty::RegionVid;
type PlaceholderRegion = ty::PlaceholderRegion;

type PlaceholderRegion = ty::PlaceholderRegion;
type Predicate = Predicate<'tcx>;
type TraitPredicate = ty::TraitPredicate<'tcx>;
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
type AliasTerm = ty::AliasTerm<'tcx>;
type NormalizesTo = ty::NormalizesTo<'tcx>;
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
type CoercePredicate = ty::CoercePredicate<'tcx>;
type ClosureKind = ty::ClosureKind;
type Clauses = ty::Clauses<'tcx>;

type Clauses = ty::Clauses<'tcx>;
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}

type GenericsOf = &'tcx ty::Generics;

fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
self.generics_of(def_id)
}

fn type_of_instantiated(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> Ty<'tcx> {
self.type_of(def_id).instantiate(self, args)
}

fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
match self.def_kind(alias.def_id) {
DefKind::AssocTy => {
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
{
ty::Inherent
} else {
ty::Projection
}
}
DefKind::OpaqueTy => ty::Opaque,
DefKind::TyAlias => ty::Weak,
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
}

fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
match self.def_kind(alias.def_id) {
DefKind::AssocTy => {
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
{
ty::AliasTermKind::InherentTy
} else {
ty::AliasTermKind::ProjectionTy
}
}
DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
DefKind::TyAlias => ty::AliasTermKind::WeakTy,
DefKind::AssocConst => ty::AliasTermKind::ProjectionConst,
DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst,
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
}

fn trait_ref_and_own_args_for_alias(
self,
def_id: Self::DefId,
args: Self::GenericArgs,
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
let trait_def_id = self.parent(def_id);
assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
let trait_generics = self.generics_of(trait_def_id);
(
ty::TraitRef::new(self, trait_def_id, args.truncate_to(self, trait_generics)),
&args[trait_generics.count()..],
)
}

fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
self.mk_args(args)
}

fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs {
self.mk_args_from_iter(args)
}

fn check_and_mk_args(
self,
def_id: DefId,
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ pub use self::list::{List, ListWithCachedTypeInfo};
pub use self::parameterized::ParameterizedOverTcx;
pub use self::pattern::{Pattern, PatternKind};
pub use self::predicate::{
Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialPredicateStableCmpExt,
ExistentialProjection, ExistentialTraitRef, NormalizesTo, OutlivesPredicate,
PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo,
OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate,
PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate,
PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef,
Expand All @@ -110,11 +110,11 @@ pub use self::region::{
};
pub use self::rvalue_scopes::RvalueScopes;
pub use self::sty::{
AliasTerm, AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind,
CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts,
CoroutineClosureArgs, CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig,
InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut,
UpvarArgs, VarianceDiagInfo,
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs,
CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, InlineConstArgs,
InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs,
VarianceDiagInfo,
};
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::ty::{
};

pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
pub type AliasTerm<'tcx> = ir::AliasTerm<TyCtxt<'tcx>>;
pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate<TyCtxt<'tcx>>;
pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
Expand Down
54 changes: 27 additions & 27 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3038,6 +3038,33 @@ define_print! {
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
}

ty::AliasTy<'tcx> {
let alias_term: ty::AliasTerm<'tcx> = (*self).into();
p!(print(alias_term))
}

ty::AliasTerm<'tcx> {
match self.kind(cx.tcx()) {
ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)),
ty::AliasTermKind::ProjectionTy
| ty::AliasTermKind::WeakTy
| ty::AliasTermKind::OpaqueTy
| ty::AliasTermKind::UnevaluatedConst
| ty::AliasTermKind::ProjectionConst => {
// If we're printing verbosely, or don't want to invoke queries
// (`is_impl_trait_in_trait`), then fall back to printing the def path.
// This is likely what you want if you're debugging the compiler anyways.
if !(cx.should_print_verbose() || with_reduced_queries())
&& cx.tcx().is_impl_trait_in_trait(self.def_id)
{
return cx.pretty_print_opaque_impl_type(self.def_id, self.args);
} else {
p!(print_def_path(self.def_id, self.args));
}
}
}
}

ty::TraitPredicate<'tcx> {
p!(print(self.trait_ref.self_ty()), ": ");
p!(pretty_print_bound_constness(self.trait_ref));
Expand Down Expand Up @@ -3205,33 +3232,6 @@ define_print_and_forward_display! {
}
}

ty::AliasTy<'tcx> {
let alias_term: ty::AliasTerm<'tcx> = (*self).into();
p!(print(alias_term))
}

ty::AliasTerm<'tcx> {
match self.kind(cx.tcx()) {
ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)),
ty::AliasTermKind::ProjectionTy
| ty::AliasTermKind::WeakTy
| ty::AliasTermKind::OpaqueTy
| ty::AliasTermKind::UnevaluatedConst
| ty::AliasTermKind::ProjectionConst => {
// If we're printing verbosely, or don't want to invoke queries
// (`is_impl_trait_in_trait`), then fall back to printing the def path.
// This is likely what you want if you're debugging the compiler anyways.
if !(cx.should_print_verbose() || with_reduced_queries())
&& cx.tcx().is_impl_trait_in_trait(self.def_id)
{
return cx.pretty_print_opaque_impl_type(self.def_id, self.args);
} else {
p!(print_def_path(self.def_id, self.args));
}
}
}
}

ty::Predicate<'tcx> {
p!(print(self.kind()))
}
Expand Down
Loading

0 comments on commit 1ad28a6

Please sign in to comment.