From b8ea6e686f996a158838e39c7515df449dcc55be Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 12 Dec 2023 18:54:49 +0000 Subject: [PATCH 1/3] Uplift ClosureKind --- compiler/rustc_errors/src/diagnostic_impls.rs | 6 ++ compiler/rustc_middle/src/ty/closure.rs | 73 +------------------ compiler/rustc_middle/src/ty/context.rs | 24 ++++++ compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 6 +- compiler/rustc_type_ir/src/interner.rs | 9 +++ compiler/rustc_type_ir/src/lib.rs | 63 ++++++++++++++++ 7 files changed, 107 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 4f77f09b26ec4..558262460c755 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -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()) + } +} diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index eaf5da130dd9c..8c29bc5a42865 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -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::*; @@ -73,72 +72,6 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap = Vec>; -/// 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)] diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index eb6fde83fcc8f..62aab72b1df1e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -158,6 +158,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, ()>; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 71ff7021ca5de..a09a511538626 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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}; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 39adfac55cef3..39d031b5be70d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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!(", "); @@ -2943,10 +2943,6 @@ define_print_and_forward_display! { } } - ty::ClosureKind { - p!(write("{}", self.as_str())) - } - ty::Predicate<'tcx> { p!(print(self.kind())) } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index c262302133bee..2e424fa11ec4a 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -89,6 +89,15 @@ pub trait Interner: Sized { 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 diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 200963ff7c5c8..f827969fb766a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -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(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(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) + } +} From 9f0849f9e059648ce18b996110276306863c5a6d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 12 Dec 2023 19:07:19 +0000 Subject: [PATCH 2/3] Uplift TypeAndMut --- .../rustc_middle/src/mir/type_foldable.rs | 1 - compiler/rustc_middle/src/ty/context.rs | 9 +--- compiler/rustc_middle/src/ty/print/pretty.rs | 8 ++-- .../rustc_middle/src/ty/structural_impls.rs | 1 - compiler/rustc_middle/src/ty/sty.rs | 11 ++--- compiler/rustc_type_ir/src/interner.rs | 7 +-- compiler/rustc_type_ir/src/macros.rs | 2 + compiler/rustc_type_ir/src/ty_kind.rs | 46 +++++++++++++++++-- .../clippy_lints/src/casts/as_ptr_cast_mut.rs | 6 +-- 9 files changed, 58 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index ea6b44d62b0fe..93a9bbf64c926 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -15,7 +15,6 @@ TrivialTypeTraversalImpls! { UserTypeAnnotationIndex, BorrowKind, CastKind, - hir::Movability, BasicBlock, SwitchTargets, CoroutineKind, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 62aab72b1df1e..ea9dc76d3cb69 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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}; @@ -88,7 +88,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Term = ty::Term<'tcx>; type Binder = Binder<'tcx, T>; - type TypeAndMut = TypeAndMut<'tcx>; type CanonicalVars = CanonicalVarInfos<'tcx>; type Ty = Ty<'tcx>; @@ -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::CanonicalVars { self.mk_canonical_var_infos(infos) } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 39d031b5be70d..8e045397b0ffa 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -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) => { @@ -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); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 0cff6b77eb606..1c75d73e5528a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -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, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 50a1b85b16918..42753f53c7b06 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -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>; pub type RegionKind<'tcx> = IrRegionKind>; pub type ConstKind<'tcx> = IrConstKind>; pub type PredicateKind<'tcx> = IrPredicateKind>; pub type ClauseKind<'tcx> = IrClauseKind>; - -#[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>; #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)] #[derive(HashStable)] diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 2e424fa11ec4a..0eccd2b4cf337 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -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 { @@ -20,7 +20,6 @@ pub trait Interner: Sized { type Term: Copy + Debug + Hash + Ord; type Binder; - type TypeAndMut: Copy + Debug + Hash + Ord; type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator>; // Kinds of tys @@ -81,8 +80,6 @@ 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::CanonicalVars; // FIXME: We should not have all these constructors on `Interner`, but as functions on some trait. diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index cfed84a35c671..82bb1bf291667 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -51,4 +51,6 @@ TrivialTypeTraversalImpls! { crate::DebruijnIndex, crate::AliasRelationDirection, crate::UniverseIndex, + crate::Mutability, + crate::Movability, } diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 72ca9199a533b..70adfbee2edc6 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -4,6 +4,8 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; use std::fmt; +use crate::fold::{FallibleTypeFolder, TypeFoldable}; +use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx}; @@ -158,7 +160,7 @@ pub enum TyKind { Slice(I::Ty), /// A raw pointer. Written as `*mut T` or `*const T` - RawPtr(I::TypeAndMut), + RawPtr(TypeAndMut), /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. @@ -410,8 +412,7 @@ impl DebugWithInfcx for TyKind { Str => write!(f, "str"), Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)), Slice(t) => write!(f, "[{:?}]", &this.wrap(t)), - RawPtr(p) => { - let (ty, mutbl) = I::ty_and_mut_to_parts(*p); + RawPtr(TypeAndMut { ty, mutbl }) => { match mutbl { Mutability::Mut => write!(f, "*mut "), Mutability::Not => write!(f, "*const "), @@ -831,3 +832,42 @@ impl DebugWithInfcx for InferTy { } } } + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + PartialOrd(bound = ""), + Ord(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Hash(bound = ""), + Debug(bound = "") +)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +pub struct TypeAndMut { + pub ty: I::Ty, + pub mutbl: Mutability, +} + +impl TypeFoldable for TypeAndMut +where + I::Ty: TypeFoldable, +{ + fn try_fold_with>(self, folder: &mut F) -> Result { + Ok(TypeAndMut { + ty: self.ty.try_fold_with(folder)?, + mutbl: self.mutbl.try_fold_with(folder)?, + }) + } +} + +impl TypeVisitable for TypeAndMut +where + I::Ty: TypeVisitable, +{ + fn visit_with>(&self, visitor: &mut V) -> std::ops::ControlFlow { + self.ty.visit_with(visitor)?; + self.mutbl.visit_with(visitor) + } +} diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs index 55294f5f38646..b55cd8833b730 100644 --- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs +++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs @@ -10,8 +10,8 @@ use super::AS_PTR_CAST_MUT; pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) { if let ty::RawPtr( - ptrty @ TypeAndMut { - mutbl: Mutability::Mut, .. + TypeAndMut { + mutbl: Mutability::Mut, ty: ptrty, }, ) = cast_to.kind() && let ty::RawPtr(TypeAndMut { @@ -34,7 +34,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cx, AS_PTR_CAST_MUT, expr.span, - &format!("casting the result of `as_ptr` to *{ptrty}"), + &format!("casting the result of `as_ptr` to *mut {ptrty}"), "replace with", format!("{recv}.as_mut_ptr()"), applicability, From 742f193ef871aff89a5d818cdb1087f41c66f75d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 14 Dec 2023 19:10:03 +0000 Subject: [PATCH 3/3] Move special methods from ClosureKind back into rustc --- compiler/rustc_hir_typeck/src/closure.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- compiler/rustc_hir_typeck/src/upvar.rs | 6 ++++- .../rustc_middle/src/middle/lang_items.rs | 11 +++++++++ compiler/rustc_middle/src/ty/context.rs | 24 ------------------- compiler/rustc_middle/src/ty/sty.rs | 9 +++++++ compiler/rustc_type_ir/src/interner.rs | 9 ------- compiler/rustc_type_ir/src/lib.rs | 21 ---------------- 8 files changed, 27 insertions(+), 57 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index f0bb18df48c94..4662ee5825e2e 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?sig, ?opt_kind); let closure_kind_ty = match opt_kind { - Some(kind) => kind.to_ty(self.tcx), + Some(kind) => Ty::from_closure_kind(self.tcx, kind), // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index bb9b849f03bc7..9ba61335e6817 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2018,7 +2018,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let new_def_id = self.probe(|_| { let trait_ref = ty::TraitRef::new( self.tcx, - call_kind.to_def_id(self.tcx), + self.tcx.fn_trait_kind_to_def_id(call_kind)?, [ callee_ty, self.next_ty_var(TypeVariableOrigin { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index c0a5818b9e5f9..ebdd74fbc388c 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -261,7 +261,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unify the (as yet unbound) type variable in the closure // args with the kind we inferred. let closure_kind_ty = closure_args.as_closure().kind_ty(); - self.demand_eqtype(span, closure_kind.to_ty(self.tcx), closure_kind_ty); + self.demand_eqtype( + span, + Ty::from_closure_kind(self.tcx, closure_kind), + closure_kind_ty, + ); // If we have an origin, store it. if let Some(mut origin) = origin { diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 9a633e04ce70d..2899e629d7914 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -36,6 +36,17 @@ impl<'tcx> TyCtxt<'tcx> { } } + /// Given a [`ty::ClosureKind`], get the [`DefId`] of its corresponding `Fn`-family + /// trait, if it is defined. + pub fn fn_trait_kind_to_def_id(self, kind: ty::ClosureKind) -> Option { + let items = self.lang_items(); + match kind { + ty::ClosureKind::Fn => items.fn_trait(), + ty::ClosureKind::FnMut => items.fn_mut_trait(), + ty::ClosureKind::FnOnce => items.fn_once_trait(), + } + } + /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits. pub fn is_fn_trait(self, id: DefId) -> bool { self.fn_trait_kind_from_def_id(id).is_some() diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index ea9dc76d3cb69..fd3058472bb54 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -151,30 +151,6 @@ 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, ()>; diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 42753f53c7b06..09c90d80e975e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -2811,6 +2811,15 @@ impl<'tcx> Ty<'tcx> { } } + /// Inverse of [`Ty::to_opt_closure_kind`]. + pub fn from_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> { + match kind { + ty::ClosureKind::Fn => tcx.types.i8, + ty::ClosureKind::FnMut => tcx.types.i16, + ty::ClosureKind::FnOnce => tcx.types.i32, + } + } + /// Fast path helper for testing if a type is `Sized`. /// /// Returning true means the type is known to be sized. Returning diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 0eccd2b4cf337..188910ecc52d1 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -86,15 +86,6 @@ pub trait Interner: Sized { 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 diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index f827969fb766a..bff938596458a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -394,27 +394,6 @@ impl ClosureKind { 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(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(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 {