From 4506681e2f53e17df0d74cd230948dc40f7d0e8d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 24 Oct 2023 00:16:14 +0000 Subject: [PATCH] Begin nightly-ifying rustc_type_ir --- Cargo.lock | 11 ++++ compiler/rustc_index/Cargo.toml | 3 +- compiler/rustc_index/src/lib.rs | 3 +- compiler/rustc_index/src/vec/tests.rs | 2 +- compiler/rustc_index_macros/Cargo.toml | 17 ++++++ compiler/rustc_index_macros/src/lib.rs | 30 ++++++++++ .../src/newtype.rs | 16 +++++- compiler/rustc_macros/src/lib.rs | 22 -------- compiler/rustc_mir_transform/src/gvn.rs | 2 +- compiler/rustc_type_ir/Cargo.toml | 21 +++++-- compiler/rustc_type_ir/src/canonical.rs | 9 ++- compiler/rustc_type_ir/src/const_kind.rs | 12 ++-- compiler/rustc_type_ir/src/fold.rs | 34 ++++++++---- compiler/rustc_type_ir/src/lib.rs | 33 ++++++----- compiler/rustc_type_ir/src/predicate_kind.rs | 17 ++++-- compiler/rustc_type_ir/src/region_kind.rs | 11 ++-- compiler/rustc_type_ir/src/ty_info.rs | 12 +++- compiler/rustc_type_ir/src/ty_kind.rs | 55 ++++++++++++------- compiler/rustc_type_ir/src/visit.rs | 6 +- 19 files changed, 214 insertions(+), 102 deletions(-) create mode 100644 compiler/rustc_index_macros/Cargo.toml create mode 100644 compiler/rustc_index_macros/src/lib.rs rename compiler/{rustc_macros => rustc_index_macros}/src/newtype.rs (94%) diff --git a/Cargo.lock b/Cargo.lock index 92bac995bc61..4b445ef695a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4041,11 +4041,22 @@ name = "rustc_index" version = "0.0.0" dependencies = [ "arrayvec", + "rustc_index_macros", "rustc_macros", "rustc_serialize", "smallvec", ] +[[package]] +name = "rustc_index_macros" +version = "0.0.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.29", + "synstructure", +] + [[package]] name = "rustc_infer" version = "0.0.0" diff --git a/compiler/rustc_index/Cargo.toml b/compiler/rustc_index/Cargo.toml index 856f8a67dd61..3a4c813b5d41 100644 --- a/compiler/rustc_index/Cargo.toml +++ b/compiler/rustc_index/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start arrayvec = { version = "0.7", default-features = false } +rustc_index_macros = { path = "../rustc_index_macros", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } smallvec = "1.8.1" @@ -14,5 +15,5 @@ smallvec = "1.8.1" [features] # tidy-alphabetical-start default = ["nightly"] -nightly = ["rustc_serialize", "rustc_macros"] +nightly = ["rustc_serialize", "rustc_macros", "rustc_index_macros/nightly"] # tidy-alphabetical-end diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 061c55c01506..c5602392c538 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -25,8 +25,7 @@ mod vec; pub use {idx::Idx, slice::IndexSlice, vec::IndexVec}; -#[cfg(feature = "rustc_macros")] -pub use rustc_macros::newtype_index; +pub use rustc_index_macros::newtype_index; /// Type size assertion. The first argument is a type and the second argument is its expected size. /// diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs index 7e5e41bd2d19..1959f4e07b7c 100644 --- a/compiler/rustc_index/src/vec/tests.rs +++ b/compiler/rustc_index/src/vec/tests.rs @@ -1,7 +1,7 @@ // Allows the macro invocation below to work use crate as rustc_index; -rustc_macros::newtype_index! { +crate::newtype_index! { #[max = 0xFFFF_FFFA] struct MyIdx {} } diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml new file mode 100644 index 000000000000..c4ca29db3c2d --- /dev/null +++ b/compiler/rustc_index_macros/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "rustc_index_macros" +version = "0.0.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +synstructure = "0.13.0" +syn = { version = "2.0.9", features = ["full"] } +proc-macro2 = "1" +quote = "1" + +[features] +default = ["nightly"] +nightly = [] \ No newline at end of file diff --git a/compiler/rustc_index_macros/src/lib.rs b/compiler/rustc_index_macros/src/lib.rs new file mode 100644 index 000000000000..f6a6175374ac --- /dev/null +++ b/compiler/rustc_index_macros/src/lib.rs @@ -0,0 +1,30 @@ +#![cfg_attr(feature = "nightly", feature(allow_internal_unstable))] +#![cfg_attr(feature = "nightly", allow(internal_features))] + +use proc_macro::TokenStream; + +mod newtype; + +/// Creates a struct type `S` that can be used as an index with +/// `IndexVec` and so on. +/// +/// There are two ways of interacting with these indices: +/// +/// - The `From` impls are the preferred way. So you can do +/// `S::from(v)` with a `usize` or `u32`. And you can convert back +/// to an integer with `u32::from(s)`. +/// +/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` +/// to create/return a value. +/// +/// Internally, the index uses a u32, so the index must not exceed +/// `u32::MAX`. You can also customize things like the `Debug` impl, +/// what traits are derived, and so forth via the macro. +#[proc_macro] +#[cfg_attr( + feature = "nightly", + allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq) +)] +pub fn newtype_index(input: TokenStream) -> TokenStream { + newtype::newtype(input) +} diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs similarity index 94% rename from compiler/rustc_macros/src/newtype.rs rename to compiler/rustc_index_macros/src/newtype.rs index 72b47de1abc2..2a974fd26281 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -24,9 +24,16 @@ impl Parse for Newtype { let mut consts = Vec::new(); let mut encodable = true; let mut ord = true; + let mut gate_rustc_only = quote! {}; + let mut gate_rustc_only_cfg = quote! { all() }; attrs.retain(|attr| match attr.path().get_ident() { Some(ident) => match &*ident.to_string() { + "gate_rustc_only" => { + gate_rustc_only = quote! { #[cfg(feature = "nightly")] }; + gate_rustc_only_cfg = quote! { feature = "nightly" }; + false + } "custom_encodable" => { encodable = false; false @@ -88,11 +95,13 @@ impl Parse for Newtype { let encodable_impls = if encodable { quote! { + #gate_rustc_only impl ::rustc_serialize::Decodable for #name { fn decode(d: &mut D) -> Self { Self::from_u32(d.read_u32()) } } + #gate_rustc_only impl ::rustc_serialize::Encodable for #name { fn encode(&self, e: &mut E) { e.emit_u32(self.private); @@ -110,6 +119,7 @@ impl Parse for Newtype { let step = if ord { quote! { + #gate_rustc_only impl ::std::iter::Step for #name { #[inline] fn steps_between(start: &Self, end: &Self) -> Option { @@ -131,6 +141,7 @@ impl Parse for Newtype { } // Safety: The implementation of `Step` upholds all invariants. + #gate_rustc_only unsafe impl ::std::iter::TrustedStep for #name {} } } else { @@ -148,6 +159,7 @@ impl Parse for Newtype { let spec_partial_eq_impl = if let Lit::Int(max) = &max { if let Ok(max_val) = max.base10_parse::() { quote! { + #gate_rustc_only impl core::option::SpecOptionPartialEq for #name { #[inline] fn eq(l: &Option, r: &Option) -> bool { @@ -173,8 +185,8 @@ impl Parse for Newtype { Ok(Self(quote! { #(#attrs)* #[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)] - #[rustc_layout_scalar_valid_range_end(#max)] - #[rustc_pass_by_value] + #[cfg_attr(#gate_rustc_only_cfg, rustc_layout_scalar_valid_range_end(#max))] + #[cfg_attr(#gate_rustc_only_cfg, rustc_pass_by_value)] #vis struct #name { private: u32, } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index a66666360324..2775bd5f6290 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -19,7 +19,6 @@ mod current_version; mod diagnostics; mod hash_stable; mod lift; -mod newtype; mod query; mod serialize; mod symbols; @@ -44,27 +43,6 @@ pub fn symbols(input: TokenStream) -> TokenStream { symbols::symbols(input.into()).into() } -/// Creates a struct type `S` that can be used as an index with -/// `IndexVec` and so on. -/// -/// There are two ways of interacting with these indices: -/// -/// - The `From` impls are the preferred way. So you can do -/// `S::from(v)` with a `usize` or `u32`. And you can convert back -/// to an integer with `u32::from(s)`. -/// -/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` -/// to create/return a value. -/// -/// Internally, the index uses a u32, so the index must not exceed -/// `u32::MAX`. You can also customize things like the `Debug` impl, -/// what traits are derived, and so forth via the macro. -#[proc_macro] -#[allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq)] -pub fn newtype_index(input: TokenStream) -> TokenStream { - newtype::newtype(input) -} - decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); decl_derive!( [HashStable_Generic, attributes(stable_hasher)] => diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 98a036182861..735960f31b37 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -88,8 +88,8 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; +use rustc_index::newtype_index; use rustc_index::IndexVec; -use rustc_macros::newtype_index; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index b39ba305913e..3a08d89cc448 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -7,9 +7,20 @@ edition = "2021" # tidy-alphabetical-start bitflags = "1.2.1" derivative = "2.2.0" -rustc_data_structures = { path = "../rustc_data_structures" } -rustc_index = { path = "../rustc_index" } -rustc_macros = { path = "../rustc_macros" } -rustc_serialize = { path = "../rustc_serialize" } -smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rustc_index = { path = "../rustc_index", default-features = false } +rustc_macros = { path = "../rustc_macros", optional = true } +rustc_serialize = { path = "../rustc_serialize", optional = true } +smallvec = { version = "1.8.1" } # tidy-alphabetical-end + +[features] +default = ["nightly"] +nightly = [ + "smallvec/may_dangle", + "smallvec/union", + "rustc_index/nightly", + "rustc_serialize", + "rustc_data_structures", + "rustc_macros", +] diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index ace9eade7f69..a0e4b4ecbfca 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -2,18 +2,19 @@ use std::fmt; use std::hash::Hash; use std::ops::ControlFlow; +#[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; -use crate::{HashStableContext, Interner, UniverseIndex}; +use crate::{Interner, UniverseIndex}; /// A "canonicalized" type `V` is one where all free inference /// variables have been rewritten to "canonical vars". These are /// numbered starting from 0 in order of first appearance. #[derive(derivative::Derivative)] #[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))] -#[derive(TyEncodable, TyDecodable)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub struct Canonical { pub value: V, pub max_universe: UniverseIndex, @@ -60,7 +61,9 @@ impl Canonical { } } -impl> HashStable for Canonical +#[cfg(feature = "nightly")] +impl> HashStable + for Canonical where I::CanonicalVars: HashStable, { diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index 33782b13ca8f..a014a4f38caf 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -1,8 +1,8 @@ -use rustc_data_structures::stable_hasher::HashStable; -use rustc_data_structures::stable_hasher::StableHasher; +#[cfg(feature = "nightly")] +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::fmt; -use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx}; +use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; use self::ConstKind::*; @@ -16,7 +16,7 @@ use self::ConstKind::*; Ord = "feature_allow_slow_enum", Hash(bound = "") )] -#[derive(TyEncodable, TyDecodable)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum ConstKind { /// A const generic parameter. Param(I::ParamConst), @@ -47,6 +47,7 @@ pub enum ConstKind { Expr(I::ExprConst), } +#[cfg(feature = "nightly")] const fn const_kind_discriminant(value: &ConstKind) -> usize { match value { Param(_) => 0, @@ -60,7 +61,8 @@ const fn const_kind_discriminant(value: &ConstKind) -> usize { } } -impl HashStable for ConstKind +#[cfg(feature = "nightly")] +impl HashStable for ConstKind where I::ParamConst: HashStable, I::InferConst: HashStable, diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index fc56400df161..8d402588398e 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -45,12 +45,18 @@ //! - u.fold_with(folder) //! ``` -use rustc_data_structures::sync::Lrc; use rustc_index::{Idx, IndexVec}; use std::mem; +use crate::Lrc; use crate::{visit::TypeVisitable, Interner}; +#[cfg(feature = "nightly")] +type Never = !; + +#[cfg(not(feature = "nightly"))] +type Never = std::convert::Infallible; + /// This trait is implemented for every type that can be folded, /// providing the skeleton of the traversal. /// @@ -79,7 +85,10 @@ pub trait TypeFoldable: TypeVisitable { /// folders. Do not override this method, to ensure coherence with /// `try_fold_with`. fn fold_with>(self, folder: &mut F) -> Self { - self.try_fold_with(folder).into_ok() + match self.try_fold_with(folder) { + Ok(t) => t, + Err(e) => match e {}, + } } } @@ -100,7 +109,10 @@ pub trait TypeSuperFoldable: TypeFoldable { /// infallible folders. Do not override this method, to ensure coherence /// with `try_super_fold_with`. fn super_fold_with>(self, folder: &mut F) -> Self { - self.try_super_fold_with(folder).into_ok() + match self.try_super_fold_with(folder) { + Ok(t) => t, + Err(e) => match e {}, + } } } @@ -113,7 +125,7 @@ pub trait TypeSuperFoldable: TypeFoldable { /// A blanket implementation of [`FallibleTypeFolder`] will defer to /// the infallible methods of this trait to ensure that the two APIs /// are coherent. -pub trait TypeFolder: FallibleTypeFolder { +pub trait TypeFolder: FallibleTypeFolder { fn interner(&self) -> I; fn fold_binder(&mut self, t: I::Binder) -> I::Binder @@ -208,13 +220,13 @@ impl FallibleTypeFolder for F where F: TypeFolder, { - type Error = !; + type Error = Never; fn interner(&self) -> I { TypeFolder::interner(self) } - fn try_fold_binder(&mut self, t: I::Binder) -> Result, !> + fn try_fold_binder(&mut self, t: I::Binder) -> Result, Never> where T: TypeFoldable, I::Binder: TypeSuperFoldable, @@ -222,25 +234,25 @@ where Ok(self.fold_binder(t)) } - fn try_fold_ty(&mut self, t: I::Ty) -> Result + fn try_fold_ty(&mut self, t: I::Ty) -> Result where I::Ty: TypeSuperFoldable, { Ok(self.fold_ty(t)) } - fn try_fold_region(&mut self, r: I::Region) -> Result { + fn try_fold_region(&mut self, r: I::Region) -> Result { Ok(self.fold_region(r)) } - fn try_fold_const(&mut self, c: I::Const) -> Result + fn try_fold_const(&mut self, c: I::Const) -> Result where I::Const: TypeSuperFoldable, { Ok(self.fold_const(c)) } - fn try_fold_predicate(&mut self, p: I::Predicate) -> Result + fn try_fold_predicate(&mut self, p: I::Predicate) -> Result where I::Predicate: TypeSuperFoldable, { @@ -311,7 +323,7 @@ impl> TypeFoldable for Lrc { // Call to `Lrc::make_mut` above guarantees that `unique` is the // sole reference to the contained value, so we can avoid doing // a checked `get_mut` here. - let slot = Lrc::get_mut_unchecked(&mut unique); + let slot = Lrc::get_mut(&mut unique).unwrap_unchecked(); // Semantically move the contained type out from `unique`, fold // it, then move the folded value back into `unique`. Should diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index e8785fff2efc..ba558aa34188 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -1,25 +1,28 @@ -#![feature(associated_type_defaults)] -#![feature(fmt_helpers_for_derive)] -#![feature(get_mut_unchecked)] -#![feature(min_specialization)] -#![feature(never_type)] -#![feature(new_uninit)] -#![feature(rustc_attrs)] -#![feature(unwrap_infallible)] +#![cfg_attr( + feature = "nightly", + feature(associated_type_defaults, min_specialization, never_type, rustc_attrs) +)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -#![allow(internal_features)] +#![cfg_attr(feature = "nightly", allow(internal_features))] +#[cfg(feature = "nightly")] extern crate self as rustc_type_ir; #[macro_use] extern crate bitflags; +#[cfg(feature = "nightly")] #[macro_use] extern crate rustc_macros; +#[cfg(feature = "nightly")] +use rustc_data_structures::sync::Lrc; use std::fmt; use std::hash::Hash; +#[cfg(not(feature = "nightly"))] +use std::sync::Arc as Lrc; +#[cfg(feature = "nightly")] pub mod codec; pub mod fold; pub mod ty_info; @@ -37,6 +40,7 @@ mod predicate_kind; mod region_kind; pub use canonical::*; +#[cfg(feature = "nightly")] pub use codec::*; pub use const_kind::*; pub use debug::{DebugWithInfcx, InferCtxtLike, WithInfcx}; @@ -90,8 +94,9 @@ rustc_index::newtype_index! { /// is the outer fn. /// /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index - #[derive(HashStable_Generic)] + #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] #[debug_format = "DebruijnIndex({})"] + #[gate_rustc_only] pub struct DebruijnIndex { const INNERMOST = 0; } @@ -173,8 +178,9 @@ pub fn debug_bound_var( } } -#[derive(Copy, Clone, PartialEq, Eq, Decodable, Encodable, Hash, HashStable_Generic)] -#[rustc_pass_by_value] +#[derive(Copy, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "nightly", derive(Decodable, Encodable, Hash, HashStable_Generic))] +#[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum Variance { Covariant, // T <: T iff A <: B -- e.g., function return type Invariant, // T <: T iff B == A -- e.g., type of mutable cell @@ -289,8 +295,9 @@ rustc_index::newtype_index! { /// declared, but a type name in a non-zero universe is a placeholder /// type -- an idealized representative of "types in general" that we /// use for checking generic functions. - #[derive(HashStable_Generic)] + #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] #[debug_format = "U{}"] + #[gate_rustc_only] pub struct UniverseIndex {} } diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 48662d426423..c2ba6afc8d01 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -1,16 +1,17 @@ +#[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::fmt; use std::ops::ControlFlow; use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; -use crate::{HashStableContext, Interner}; +use crate::Interner; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Hash(bound = ""))] -#[derive(TyEncodable, TyDecodable)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum ClauseKind { /// Corresponds to `where Foo: Bar`. `Foo` here would be /// the `Self` type of the trait reference and `A`, `B`, and `C` @@ -67,6 +68,7 @@ impl PartialEq for ClauseKind { impl Eq for ClauseKind {} +#[cfg(feature = "nightly")] fn clause_kind_discriminant(value: &ClauseKind) -> usize { match value { ClauseKind::Trait(_) => 0, @@ -79,7 +81,8 @@ fn clause_kind_discriminant(value: &ClauseKind) -> usize { } } -impl HashStable for ClauseKind +#[cfg(feature = "nightly")] +impl HashStable for ClauseKind where I::Ty: HashStable, I::Const: HashStable, @@ -161,7 +164,7 @@ where #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Hash(bound = ""))] -#[derive(TyEncodable, TyDecodable)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum PredicateKind { /// Prove a clause Clause(ClauseKind), @@ -239,6 +242,7 @@ impl PartialEq for PredicateKind { impl Eq for PredicateKind {} +#[cfg(feature = "nightly")] fn predicate_kind_discriminant(value: &PredicateKind) -> usize { match value { PredicateKind::Clause(_) => 0, @@ -252,7 +256,8 @@ fn predicate_kind_discriminant(value: &PredicateKind) -> usize { } } -impl HashStable for PredicateKind +#[cfg(feature = "nightly")] +impl HashStable for PredicateKind where I::DefId: HashStable, I::Const: HashStable, @@ -361,7 +366,7 @@ where } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[cfg_attr(feature = "nightly", derive(HashStable_Generic, Encodable, Decodable))] pub enum AliasRelationDirection { Equate, Subtype, diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 5d3ce49bc8f7..ddd10db1c6c7 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -1,8 +1,8 @@ -use rustc_data_structures::stable_hasher::HashStable; -use rustc_data_structures::stable_hasher::StableHasher; +#[cfg(feature = "nightly")] +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::fmt; -use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx}; +use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx}; use self::RegionKind::*; @@ -121,7 +121,7 @@ use self::RegionKind::*; Ord = "feature_allow_slow_enum", Hash(bound = "") )] -#[derive(TyEncodable, TyDecodable)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum RegionKind { /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. /// @@ -261,8 +261,9 @@ impl fmt::Debug for RegionKind { } } +#[cfg(feature = "nightly")] // This is not a derived impl because a derive would require `I: HashStable` -impl HashStable for RegionKind +impl HashStable for RegionKind where I::EarlyParamRegion: HashStable, I::BoundRegion: HashStable, diff --git a/compiler/rustc_type_ir/src/ty_info.rs b/compiler/rustc_type_ir/src/ty_info.rs index d986e310c329..0e4930552c21 100644 --- a/compiler/rustc_type_ir/src/ty_info.rs +++ b/compiler/rustc_type_ir/src/ty_info.rs @@ -1,4 +1,6 @@ +#[cfg(feature = "nightly")] use rustc_data_structures::fingerprint::Fingerprint; +#[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; @@ -16,6 +18,8 @@ use crate::{DebruijnIndex, TypeFlags}; #[derive(Copy, Clone)] pub struct WithCachedTypeInfo { pub internee: T, + + #[cfg(feature = "nightly")] pub stable_hash: Fingerprint, /// This field provides fast access to information that is also contained @@ -81,14 +85,16 @@ impl Deref for WithCachedTypeInfo { impl Hash for WithCachedTypeInfo { #[inline] fn hash(&self, s: &mut H) { + #[cfg(feature = "nightly")] if self.stable_hash != Fingerprint::ZERO { - self.stable_hash.hash(s) - } else { - self.internee.hash(s) + return self.stable_hash.hash(s); } + + self.internee.hash(s) } } +#[cfg(feature = "nightly")] impl, CTX> HashStable for WithCachedTypeInfo { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) { diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 09a9a332269e..f31c5069b155 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -1,11 +1,11 @@ #![allow(rustc::usage_of_ty_tykind)] +#[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +#[cfg(feature = "nightly")] use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; use std::fmt; -use std::mem::discriminant; -use crate::HashStableContext; use crate::Interner; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx}; @@ -13,8 +13,8 @@ use self::TyKind::*; /// The movability of a coroutine / closure literal: /// whether a coroutine contains self-references, causing it to be `!Unpin`. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable, Debug, Copy)] -#[derive(HashStable_Generic)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum Movability { /// May contain self-references, `!Unpin`. Static, @@ -23,7 +23,7 @@ pub enum Movability { } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] -#[derive(HashStable_Generic, Encodable, Decodable)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum Mutability { // N.B. Order is deliberate, so that Not < Mut Not, @@ -75,7 +75,7 @@ impl Mutability { /// Specifies how a trait object is represented. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum DynKind { /// An unsized `dyn Trait` object Dyn, @@ -89,7 +89,7 @@ pub enum DynKind { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum AliasKind { /// A projection `::AssocType`. /// Can get normalized away if monomorphic enough. @@ -109,7 +109,7 @@ pub enum AliasKind { /// /// Types written by the user start out as `hir::TyKind` and get /// converted to this representation using `AstConv::ast_ty_to_ty`. -#[rustc_diagnostic_item = "IrTyKind"] +#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[derive(derivative::Derivative)] #[derivative( Clone(bound = ""), @@ -119,7 +119,7 @@ pub enum AliasKind { Ord = "feature_allow_slow_enum", Hash(bound = "") )] -#[derive(TyEncodable, TyDecodable)] +#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum TyKind { /// The primitive boolean type. Written as `bool`. Bool, @@ -407,7 +407,7 @@ impl DebugWithInfcx for TyKind { write!(f, ">") } - Foreign(d) => f.debug_tuple_field1_finish("Foreign", d), + Foreign(d) => f.debug_tuple("Foreign").field(d).finish(), Str => write!(f, "str"), Array(t, c) => write!(f, "[{:?}; {:?}]", &this.wrap(t), &this.wrap(c)), Slice(t) => write!(f, "[{:?}]", &this.wrap(t)), @@ -423,7 +423,7 @@ impl DebugWithInfcx for TyKind { Mutability::Mut => write!(f, "&{:?} mut {:?}", &this.wrap(r), &this.wrap(t)), Mutability::Not => write!(f, "&{:?} {:?}", &this.wrap(r), &this.wrap(t)), }, - FnDef(d, s) => f.debug_tuple_field2_finish("FnDef", d, &this.wrap(s)), + FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&this.wrap(s)).finish(), FnPtr(s) => write!(f, "{:?}", &this.wrap(s)), Dynamic(p, r, repr) => match repr { DynKind::Dyn => write!(f, "dyn {:?} + {:?}", &this.wrap(p), &this.wrap(r)), @@ -431,10 +431,12 @@ impl DebugWithInfcx for TyKind { write!(f, "dyn* {:?} + {:?}", &this.wrap(p), &this.wrap(r)) } }, - Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, &this.wrap(s)), - Coroutine(d, s, m) => f.debug_tuple_field3_finish("Coroutine", d, &this.wrap(s), m), + Closure(d, s) => f.debug_tuple("Closure").field(d).field(&this.wrap(s)).finish(), + Coroutine(d, s, m) => { + f.debug_tuple("Coroutine").field(d).field(&this.wrap(s)).field(m).finish() + } CoroutineWitness(d, s) => { - f.debug_tuple_field2_finish("CoroutineWitness", d, &this.wrap(s)) + f.debug_tuple("CoroutineWitness").field(d).field(&this.wrap(s)).finish() } Never => write!(f, "!"), Tuple(t) => { @@ -453,7 +455,7 @@ impl DebugWithInfcx for TyKind { } write!(f, ")") } - Alias(i, a) => f.debug_tuple_field2_finish("Alias", i, &this.wrap(a)), + Alias(i, a) => f.debug_tuple("Alias").field(i).field(&this.wrap(a)).finish(), Param(p) => write!(f, "{p:?}"), Bound(d, b) => crate::debug_bound_var(f, *d, b), Placeholder(p) => write!(f, "{p:?}"), @@ -471,8 +473,9 @@ impl fmt::Debug for TyKind { } // This is not a derived impl because a derive would require `I: HashStable` +#[cfg(feature = "nightly")] #[allow(rustc::usage_of_ty_tykind)] -impl HashStable for TyKind +impl HashStable for TyKind where I::AdtDef: HashStable, I::DefId: HashStable, @@ -583,7 +586,7 @@ where } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum IntTy { Isize, I8, @@ -641,7 +644,7 @@ impl IntTy { } #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum UintTy { Usize, U8, @@ -699,7 +702,7 @@ impl UintTy { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[derive(Encodable, Decodable, HashStable_Generic)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_Generic))] pub enum FloatTy { F32, F64, @@ -733,18 +736,21 @@ pub struct FloatVarValue(pub FloatTy); rustc_index::newtype_index! { /// A **ty**pe **v**ariable **ID**. #[debug_format = "?{}t"] + #[gate_rustc_only] pub struct TyVid {} } rustc_index::newtype_index! { /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. #[debug_format = "?{}i"] + #[gate_rustc_only] pub struct IntVid {} } rustc_index::newtype_index! { /// A **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. #[debug_format = "?{}f"] + #[gate_rustc_only] pub struct FloatVid {} } @@ -753,7 +759,8 @@ rustc_index::newtype_index! { /// E.g., if we have an empty array (`[]`), then we create a fresh /// type variable for the element type since we won't know until it's /// used what the element type is supposed to be. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable))] pub enum InferTy { /// A type variable. TyVar(TyVid), @@ -786,6 +793,7 @@ pub enum InferTy { /// Raw `TyVid` are used as the unification key for `sub_relations`; /// they carry no values. +#[cfg(feature = "nightly")] impl UnifyKey for TyVid { type Value = (); #[inline] @@ -801,8 +809,10 @@ impl UnifyKey for TyVid { } } +#[cfg(feature = "nightly")] impl EqUnifyValue for IntVarValue {} +#[cfg(feature = "nightly")] impl UnifyKey for IntVid { type Value = Option; #[inline] // make this function eligible for inlining - it is quite hot. @@ -818,8 +828,10 @@ impl UnifyKey for IntVid { } } +#[cfg(feature = "nightly")] impl EqUnifyValue for FloatVarValue {} +#[cfg(feature = "nightly")] impl UnifyKey for FloatVid { type Value = Option; #[inline] @@ -835,10 +847,11 @@ impl UnifyKey for FloatVid { } } +#[cfg(feature = "nightly")] impl HashStable for InferTy { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { use InferTy::*; - discriminant(self).hash_stable(ctx, hasher); + std::mem::discriminant(self).hash_stable(ctx, hasher); match self { TyVar(_) | IntVar(_) | FloatVar(_) => { panic!("type variables should not be hashed: {self:?}") diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 9c7b8156b043..7aa990046675 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -41,12 +41,12 @@ //! - u.visit_with(visitor) //! ``` -use rustc_data_structures::sync::Lrc; use rustc_index::{Idx, IndexVec}; use std::fmt; use std::ops::ControlFlow; use crate::Interner; +use crate::Lrc; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. @@ -82,8 +82,12 @@ pub trait TypeSuperVisitable: TypeVisitable { /// method defined for every type of interest. Each such method has a default /// that recurses into the type's fields in a non-custom fashion. pub trait TypeVisitor: Sized { + #[cfg(feature = "nightly")] type BreakTy = !; + #[cfg(not(feature = "nightly"))] + type BreakTy; + fn visit_binder>(&mut self, t: &I::Binder) -> ControlFlow where I::Binder: TypeSuperVisitable,