Skip to content

Commit f45a07c

Browse files
Uplift ClosureKind
1 parent 835ed00 commit f45a07c

File tree

7 files changed

+107
-76
lines changed

7 files changed

+107
-76
lines changed

compiler/rustc_errors/src/diagnostic_impls.rs

+6
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,9 @@ pub struct IndicateAnonymousLifetime {
378378
pub count: usize,
379379
pub suggestion: String,
380380
}
381+
382+
impl IntoDiagnosticArg for type_ir::ClosureKind {
383+
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
384+
DiagnosticArgValue::Str(self.as_str().into())
385+
}
386+
}

compiler/rustc_middle/src/ty/closure.rs

+3-70
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@ use std::fmt::Write;
77

88
use crate::query::Providers;
99
use rustc_data_structures::fx::FxIndexMap;
10-
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
11-
use rustc_hir::def_id::{DefId, LocalDefId};
12-
use rustc_hir::{self as hir, LangItem};
10+
use rustc_hir as hir;
11+
use rustc_hir::def_id::LocalDefId;
1312
use rustc_span::def_id::LocalDefIdMap;
1413
use rustc_span::symbol::Ident;
1514
use rustc_span::{Span, Symbol};
1615

17-
use super::{Ty, TyCtxt};
16+
use super::TyCtxt;
1817

1918
use self::BorrowKind::*;
2019

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

76-
/// Represents the various closure traits in the language. This
77-
/// will determine the type of the environment (`self`, in the
78-
/// desugaring) argument that the closure expects.
79-
///
80-
/// You can get the environment type of a closure using
81-
/// `tcx.closure_env_ty()`.
82-
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
83-
#[derive(HashStable)]
84-
pub enum ClosureKind {
85-
// Warning: Ordering is significant here! The ordering is chosen
86-
// because the trait Fn is a subtrait of FnMut and so in turn, and
87-
// hence we order it so that Fn < FnMut < FnOnce.
88-
Fn,
89-
FnMut,
90-
FnOnce,
91-
}
92-
93-
impl ClosureKind {
94-
/// This is the initial value used when doing upvar inference.
95-
pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
96-
97-
pub const fn as_str(self) -> &'static str {
98-
match self {
99-
ClosureKind::Fn => "Fn",
100-
ClosureKind::FnMut => "FnMut",
101-
ClosureKind::FnOnce => "FnOnce",
102-
}
103-
}
104-
105-
/// Returns `true` if a type that impls this closure kind
106-
/// must also implement `other`.
107-
pub fn extends(self, other: ty::ClosureKind) -> bool {
108-
self <= other
109-
}
110-
111-
/// Converts `self` to a [`DefId`] of the corresponding trait.
112-
///
113-
/// Note: the inverse of this function is [`TyCtxt::fn_trait_kind_from_def_id`].
114-
pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId {
115-
tcx.require_lang_item(
116-
match self {
117-
ClosureKind::Fn => LangItem::Fn,
118-
ClosureKind::FnMut => LangItem::FnMut,
119-
ClosureKind::FnOnce => LangItem::FnOnce,
120-
},
121-
None,
122-
)
123-
}
124-
125-
/// Returns the representative scalar type for this closure kind.
126-
/// See `Ty::to_opt_closure_kind` for more details.
127-
pub fn to_ty<'tcx>(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
128-
match self {
129-
ClosureKind::Fn => tcx.types.i8,
130-
ClosureKind::FnMut => tcx.types.i16,
131-
ClosureKind::FnOnce => tcx.types.i32,
132-
}
133-
}
134-
}
135-
136-
impl IntoDiagnosticArg for ClosureKind {
137-
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
138-
DiagnosticArgValue::Str(self.as_str().into())
139-
}
140-
}
141-
14275
/// A composite describing a `Place` that is captured by a closure.
14376
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
14477
#[derive(TypeFoldable, TypeVisitable)]

compiler/rustc_middle/src/ty/context.rs

+24
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,30 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
158158
) -> Self::Const {
159159
Const::new_bound(self, debruijn, var, ty)
160160
}
161+
162+
fn fn_def_id(self) -> Self::DefId {
163+
self.require_lang_item(hir::LangItem::Fn, None)
164+
}
165+
166+
fn fn_mut_def_id(self) -> Self::DefId {
167+
self.require_lang_item(hir::LangItem::FnMut, None)
168+
}
169+
170+
fn fn_once_def_id(self) -> Self::DefId {
171+
self.require_lang_item(hir::LangItem::FnOnce, None)
172+
}
173+
174+
fn i8_type(self) -> Self::Ty {
175+
self.types.i8
176+
}
177+
178+
fn i16_type(self) -> Self::Ty {
179+
self.types.i16
180+
}
181+
182+
fn i32_type(self) -> Self::Ty {
183+
self.types.i32
184+
}
161185
}
162186

163187
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ pub use self::binding::BindingMode;
7575
pub use self::binding::BindingMode::*;
7676
pub use self::closure::{
7777
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
78-
CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
78+
CapturedPlace, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
7979
RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
8080
};
8181
pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};

compiler/rustc_middle/src/ty/print/pretty.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
16801680
self.wrap_binder(&sig, |sig, cx| {
16811681
define_scoped_cx!(cx);
16821682

1683-
p!(print(kind), "(");
1683+
p!(write("{kind}("));
16841684
for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
16851685
if i > 0 {
16861686
p!(", ");
@@ -2943,10 +2943,6 @@ define_print_and_forward_display! {
29432943
}
29442944
}
29452945

2946-
ty::ClosureKind {
2947-
p!(write("{}", self.as_str()))
2948-
}
2949-
29502946
ty::Predicate<'tcx> {
29512947
p!(print(self.kind()))
29522948
}

compiler/rustc_type_ir/src/interner.rs

+9
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ pub trait Interner: Sized {
8989
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
9090
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
9191
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
92+
93+
// FIXME: these could be consolidated into some "WellKnownTraits" thing like chalk does.
94+
fn fn_def_id(self) -> Self::DefId;
95+
fn fn_mut_def_id(self) -> Self::DefId;
96+
fn fn_once_def_id(self) -> Self::DefId;
97+
98+
fn i8_type(self) -> Self::Ty;
99+
fn i16_type(self) -> Self::Ty;
100+
fn i32_type(self) -> Self::Ty;
92101
}
93102

94103
/// Common capabilities of placeholder kinds

compiler/rustc_type_ir/src/lib.rs

+63
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,66 @@ rustc_index::newtype_index! {
359359
#[gate_rustc_only]
360360
pub struct BoundVar {}
361361
}
362+
363+
/// Represents the various closure traits in the language. This
364+
/// will determine the type of the environment (`self`, in the
365+
/// desugaring) argument that the closure expects.
366+
///
367+
/// You can get the environment type of a closure using
368+
/// `tcx.closure_env_ty()`.
369+
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
370+
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
371+
pub enum ClosureKind {
372+
// Warning: Ordering is significant here! The ordering is chosen
373+
// because the trait Fn is a subtrait of FnMut and so in turn, and
374+
// hence we order it so that Fn < FnMut < FnOnce.
375+
Fn,
376+
FnMut,
377+
FnOnce,
378+
}
379+
380+
impl ClosureKind {
381+
/// This is the initial value used when doing upvar inference.
382+
pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
383+
384+
pub const fn as_str(self) -> &'static str {
385+
match self {
386+
ClosureKind::Fn => "Fn",
387+
ClosureKind::FnMut => "FnMut",
388+
ClosureKind::FnOnce => "FnOnce",
389+
}
390+
}
391+
392+
/// Returns `true` if a type that impls this closure kind
393+
/// must also implement `other`.
394+
pub fn extends(self, other: ClosureKind) -> bool {
395+
self <= other
396+
}
397+
398+
/// Converts `self` to a [`DefId`] of the corresponding trait.
399+
///
400+
/// Note: the inverse of this function is `TyCtxt::fn_trait_kind_from_def_id`.
401+
pub fn to_def_id<I: Interner>(self, interner: I) -> I::DefId {
402+
match self {
403+
ClosureKind::Fn => interner.fn_def_id(),
404+
ClosureKind::FnMut => interner.fn_mut_def_id(),
405+
ClosureKind::FnOnce => interner.fn_once_def_id(),
406+
}
407+
}
408+
409+
/// Returns the representative scalar type for this closure kind.
410+
/// See `Ty::to_opt_closure_kind` for more details.
411+
pub fn to_ty<I: Interner>(self, interner: I) -> I::Ty {
412+
match self {
413+
ClosureKind::Fn => interner.i8_type(),
414+
ClosureKind::FnMut => interner.i16_type(),
415+
ClosureKind::FnOnce => interner.i32_type(),
416+
}
417+
}
418+
}
419+
420+
impl fmt::Display for ClosureKind {
421+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
422+
self.as_str().fmt(f)
423+
}
424+
}

0 commit comments

Comments
 (0)