Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uplift TypeAndMut and ClosureKind to rustc_type_ir #118888

Merged
merged 3 commits into from Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Expand Up @@ -378,3 +378,9 @@ pub struct IndicateAnonymousLifetime {
pub count: usize,
pub suggestion: String,
}

impl IntoDiagnosticArg for type_ir::ClosureKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(self.as_str().into())
}
}
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/mir/type_foldable.rs
Expand Up @@ -15,7 +15,6 @@ TrivialTypeTraversalImpls! {
UserTypeAnnotationIndex,
BorrowKind,
CastKind,
hir::Movability,
BasicBlock,
SwitchTargets,
CoroutineKind,
Expand Down
73 changes: 3 additions & 70 deletions compiler/rustc_middle/src/ty/closure.rs
Expand Up @@ -7,14 +7,13 @@ use std::fmt::Write;

use crate::query::Providers;
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, LangItem};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_span::def_id::LocalDefIdMap;
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol};

use super::{Ty, TyCtxt};
use super::TyCtxt;

use self::BorrowKind::*;

Expand Down Expand Up @@ -73,72 +72,6 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis
/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.
pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;

/// Represents the various closure traits in the language. This
/// will determine the type of the environment (`self`, in the
/// desugaring) argument that the closure expects.
///
/// You can get the environment type of a closure using
/// `tcx.closure_env_ty()`.
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable)]
pub enum ClosureKind {
// Warning: Ordering is significant here! The ordering is chosen
// because the trait Fn is a subtrait of FnMut and so in turn, and
// hence we order it so that Fn < FnMut < FnOnce.
Fn,
FnMut,
FnOnce,
}

impl ClosureKind {
/// This is the initial value used when doing upvar inference.
pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;

pub const fn as_str(self) -> &'static str {
match self {
ClosureKind::Fn => "Fn",
ClosureKind::FnMut => "FnMut",
ClosureKind::FnOnce => "FnOnce",
}
}

/// Returns `true` if a type that impls this closure kind
/// must also implement `other`.
pub fn extends(self, other: ty::ClosureKind) -> bool {
self <= other
}

/// Converts `self` to a [`DefId`] of the corresponding trait.
///
/// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`].
pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
tcx.require_lang_item(
match self {
ClosureKind::Fn => LangItem::Fn,
ClosureKind::FnMut => LangItem::FnMut,
ClosureKind::FnOnce => LangItem::FnOnce,
},
None,
)
}

/// Returns the representative scalar type for this closure kind.
/// See `Ty::to_opt_closure_kind` for more details.
pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self {
ClosureKind::Fn => tcx.types.i8,
ClosureKind::FnMut => tcx.types.i16,
ClosureKind::FnOnce => tcx.types.i32,
}
}
}

impl IntoDiagnosticArg for ClosureKind {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(self.as_str().into())
}
}

/// A composite describing a `Place` that is captured by a closure.
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
Expand Down
33 changes: 25 additions & 8 deletions compiler/rustc_middle/src/ty/context.rs
Expand Up @@ -28,7 +28,7 @@ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
TypeAndMut, Visibility,
Visibility,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
Expand Down Expand Up @@ -88,7 +88,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type Term = ty::Term<'tcx>;

type Binder<T> = Binder<'tcx, T>;
type TypeAndMut = TypeAndMut<'tcx>;
type CanonicalVars = CanonicalVarInfos<'tcx>;

type Ty = Ty<'tcx>;
Expand Down Expand Up @@ -128,12 +127,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type CoercePredicate = ty::CoercePredicate<'tcx>;
type ClosureKind = ty::ClosureKind;

fn ty_and_mut_to_parts(
TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>,
) -> (Self::Ty, ty::Mutability) {
(ty, mutbl)
}

fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}
Expand All @@ -158,6 +151,30 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
) -> Self::Const {
Const::new_bound(self, debruijn, var, ty)
}

fn fn_def_id(self) -> Self::DefId {
self.require_lang_item(hir::LangItem::Fn, None)
}

fn fn_mut_def_id(self) -> Self::DefId {
self.require_lang_item(hir::LangItem::FnMut, None)
}

fn fn_once_def_id(self) -> Self::DefId {
self.require_lang_item(hir::LangItem::FnOnce, None)
}

fn i8_type(self) -> Self::Ty {
self.types.i8
}

fn i16_type(self) -> Self::Ty {
self.types.i16
}

fn i32_type(self) -> Self::Ty {
self.types.i32
}
}

type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Expand Up @@ -75,7 +75,7 @@ pub use self::binding::BindingMode;
pub use self::binding::BindingMode::*;
pub use self::closure::{
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
CapturedPlace, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
};
pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Expand Up @@ -1680,7 +1680,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
self.wrap_binder(&sig, |sig, cx| {
define_scoped_cx!(cx);

p!(print(kind), "(");
p!(write("{kind}("));
for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
if i > 0 {
p!(", ");
Expand Down Expand Up @@ -2754,6 +2754,10 @@ forward_display_to_print! {
define_print! {
(self, cx):

ty::TypeAndMut<'tcx> {
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
}

ty::ClauseKind<'tcx> {
match *self {
ty::ClauseKind::Trait(ref data) => {
Expand Down Expand Up @@ -2799,10 +2803,6 @@ define_print_and_forward_display! {
p!("{{", comma_sep(self.iter()), "}}")
}

ty::TypeAndMut<'tcx> {
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
}

ty::ExistentialTraitRef<'tcx> {
// Use a type that can't appear in defaults of type parameters.
let dummy_self = Ty::new_fresh(cx.tcx(),0);
Expand Down Expand Up @@ -2943,10 +2943,6 @@ define_print_and_forward_display! {
}
}

ty::ClosureKind {
p!(write("{}", self.as_str()))
}

ty::Predicate<'tcx> {
p!(print(self.kind()))
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/ty/structural_impls.rs
Expand Up @@ -440,7 +440,6 @@ TrivialTypeTraversalImpls! {
// interners).
TrivialTypeTraversalAndLiftImpls! {
::rustc_hir::def_id::DefId,
::rustc_hir::Mutability,
::rustc_hir::Unsafety,
::rustc_target::spec::abi::Abi,
crate::ty::ClosureKind,
Expand Down
11 changes: 3 additions & 8 deletions compiler/rustc_middle/src/ty/sty.rs
Expand Up @@ -42,23 +42,18 @@ use rustc_type_ir::PredicateKind as IrPredicateKind;
use rustc_type_ir::RegionKind as IrRegionKind;
use rustc_type_ir::TyKind as IrTyKind;
use rustc_type_ir::TyKind::*;
use rustc_type_ir::TypeAndMut as IrTypeAndMut;

use super::GenericParamDefKind;

// Re-export the `TyKind` from `rustc_type_ir` here for convenience
// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
#[rustc_diagnostic_item = "TyKind"]
pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
pub type PredicateKind<'tcx> = IrPredicateKind<TyCtxt<'tcx>>;
pub type ClauseKind<'tcx> = IrClauseKind<TyCtxt<'tcx>>;

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
pub struct TypeAndMut<'tcx> {
pub ty: Ty<'tcx>,
pub mutbl: hir::Mutability,
}
pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>;

#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
#[derive(HashStable)]
Expand Down
16 changes: 11 additions & 5 deletions compiler/rustc_type_ir/src/interner.rs
Expand Up @@ -3,8 +3,8 @@ use std::fmt::Debug;
use std::hash::Hash;

use crate::{
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, Mutability, RegionKind,
TyKind, UniverseIndex,
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind,
UniverseIndex,
};

pub trait Interner: Sized {
Expand All @@ -20,7 +20,6 @@ pub trait Interner: Sized {
type Term: Copy + Debug + Hash + Ord;

type Binder<T>;
type TypeAndMut: Copy + Debug + Hash + Ord;
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;

// Kinds of tys
Expand Down Expand Up @@ -81,14 +80,21 @@ pub trait Interner: Sized {
type CoercePredicate: Copy + Debug + Hash + Eq;
type ClosureKind: Copy + Debug + Hash + Eq;

fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability);

fn mk_canonical_var_infos(self, infos: &[CanonicalVarInfo<Self>]) -> Self::CanonicalVars;

// FIXME: We should not have all these constructors on `Interner`, but as functions on some trait.
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;

// FIXME: these could be consolidated into some "WellKnownTraits" thing like chalk does.
fn fn_def_id(self) -> Self::DefId;
fn fn_mut_def_id(self) -> Self::DefId;
fn fn_once_def_id(self) -> Self::DefId;

fn i8_type(self) -> Self::Ty;
fn i16_type(self) -> Self::Ty;
fn i32_type(self) -> Self::Ty;
}

/// Common capabilities of placeholder kinds
Expand Down
63 changes: 63 additions & 0 deletions compiler/rustc_type_ir/src/lib.rs
Expand Up @@ -359,3 +359,66 @@ rustc_index::newtype_index! {
#[gate_rustc_only]
pub struct BoundVar {}
}

/// Represents the various closure traits in the language. This
/// will determine the type of the environment (`self`, in the
/// desugaring) argument that the closure expects.
///
/// You can get the environment type of a closure using
/// `tcx.closure_env_ty()`.
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
pub enum ClosureKind {
// Warning: Ordering is significant here! The ordering is chosen
// because the trait Fn is a subtrait of FnMut and so in turn, and
// hence we order it so that Fn < FnMut < FnOnce.
Fn,
FnMut,
FnOnce,
}

impl ClosureKind {
/// This is the initial value used when doing upvar inference.
pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;

pub const fn as_str(self) -> &'static str {
match self {
ClosureKind::Fn => "Fn",
ClosureKind::FnMut => "FnMut",
ClosureKind::FnOnce => "FnOnce",
}
}

/// Returns `true` if a type that impls this closure kind
/// must also implement `other`.
pub fn extends(self, other: ClosureKind) -> bool {
self <= other
}

/// Converts `self` to a `DefId` of the corresponding trait.
///
/// Note: the inverse of this function is `TyCtxt::fn_trait_kind_from_def_id`.
pub fn to_def_id<I: Interner>(self, interner: I) -> I::DefId {
match self {
ClosureKind::Fn => interner.fn_def_id(),
ClosureKind::FnMut => interner.fn_mut_def_id(),
ClosureKind::FnOnce => interner.fn_once_def_id(),
}
}

/// Returns the representative scalar type for this closure kind.
/// See `Ty::to_opt_closure_kind` for more details.
pub fn to_ty<I: Interner>(self, interner: I) -> I::Ty {
match self {
ClosureKind::Fn => interner.i8_type(),
ClosureKind::FnMut => interner.i16_type(),
ClosureKind::FnOnce => interner.i32_type(),
}
}
jackh726 marked this conversation as resolved.
Show resolved Hide resolved
}

impl fmt::Display for ClosureKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_str().fmt(f)
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_type_ir/src/macros.rs
Expand Up @@ -51,4 +51,6 @@ TrivialTypeTraversalImpls! {
crate::DebruijnIndex,
crate::AliasRelationDirection,
crate::UniverseIndex,
crate::Mutability,
crate::Movability,
}