mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Uplift ClosureKind
This commit is contained in:
parent
835ed0021e
commit
b8ea6e686f
@ -378,3 +378,9 @@ pub struct IndicateAnonymousLifetime {
|
|||||||
pub count: usize,
|
pub count: usize,
|
||||||
pub suggestion: String,
|
pub suggestion: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoDiagnosticArg for type_ir::ClosureKind {
|
||||||
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||||
|
DiagnosticArgValue::Str(self.as_str().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,14 +7,13 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
use crate::query::Providers;
|
use crate::query::Providers;
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::{self as hir, LangItem};
|
|
||||||
use rustc_span::def_id::LocalDefIdMap;
|
use rustc_span::def_id::LocalDefIdMap;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
use super::{Ty, TyCtxt};
|
use super::TyCtxt;
|
||||||
|
|
||||||
use self::BorrowKind::*;
|
use self::BorrowKind::*;
|
||||||
|
|
||||||
@ -73,72 +72,6 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis
|
|||||||
/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.
|
/// Part of `MinCaptureInformationMap`; List of `CapturePlace`s.
|
||||||
pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
|
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.
|
/// A composite describing a `Place` that is captured by a closure.
|
||||||
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
#[derive(TypeFoldable, TypeVisitable)]
|
#[derive(TypeFoldable, TypeVisitable)]
|
||||||
|
@ -158,6 +158,30 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
) -> Self::Const {
|
) -> Self::Const {
|
||||||
Const::new_bound(self, debruijn, var, ty)
|
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>, ()>;
|
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||||
|
@ -75,7 +75,7 @@ pub use self::binding::BindingMode;
|
|||||||
pub use self::binding::BindingMode::*;
|
pub use self::binding::BindingMode::*;
|
||||||
pub use self::closure::{
|
pub use self::closure::{
|
||||||
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
|
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,
|
RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
|
||||||
};
|
};
|
||||||
pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
|
pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
|
||||||
|
@ -1680,7 +1680,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
self.wrap_binder(&sig, |sig, cx| {
|
self.wrap_binder(&sig, |sig, cx| {
|
||||||
define_scoped_cx!(cx);
|
define_scoped_cx!(cx);
|
||||||
|
|
||||||
p!(print(kind), "(");
|
p!(write("{kind}("));
|
||||||
for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
|
for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
p!(", ");
|
p!(", ");
|
||||||
@ -2943,10 +2943,6 @@ define_print_and_forward_display! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ClosureKind {
|
|
||||||
p!(write("{}", self.as_str()))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Predicate<'tcx> {
|
ty::Predicate<'tcx> {
|
||||||
p!(print(self.kind()))
|
p!(print(self.kind()))
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,15 @@ pub trait Interner: Sized {
|
|||||||
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
|
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_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
|
||||||
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
|
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
|
/// Common capabilities of placeholder kinds
|
||||||
|
@ -359,3 +359,66 @@ rustc_index::newtype_index! {
|
|||||||
#[gate_rustc_only]
|
#[gate_rustc_only]
|
||||||
pub struct BoundVar {}
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ClosureKind {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.as_str().fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user