Begin nightly-ifying rustc_type_ir

This commit is contained in:
Michael Goulet 2023-10-24 00:16:14 +00:00
parent 2831701757
commit 4506681e2f
19 changed files with 214 additions and 102 deletions

View File

@ -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"

View File

@ -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

View File

@ -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.
///

View File

@ -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 {}
}

View File

@ -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 = []

View File

@ -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)
}

View File

@ -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<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for #name {
fn decode(d: &mut D) -> Self {
Self::from_u32(d.read_u32())
}
}
#gate_rustc_only
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> 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<usize> {
@ -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::<u32>() {
quote! {
#gate_rustc_only
impl core::option::SpecOptionPartialEq for #name {
#[inline]
fn eq(l: &Option<Self>, r: &Option<Self>) -> 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,
}

View File

@ -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)] =>

View File

@ -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::*;

View File

@ -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",
]

View File

@ -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<I: Interner, V> {
pub value: V,
pub max_universe: UniverseIndex,
@ -60,7 +61,9 @@ impl<I: Interner, V> Canonical<I, V> {
}
}
impl<CTX: HashStableContext, I: Interner, V: HashStable<CTX>> HashStable<CTX> for Canonical<I, V>
#[cfg(feature = "nightly")]
impl<CTX: crate::HashStableContext, I: Interner, V: HashStable<CTX>> HashStable<CTX>
for Canonical<I, V>
where
I::CanonicalVars: HashStable<CTX>,
{

View File

@ -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<I: Interner> {
/// A const generic parameter.
Param(I::ParamConst),
@ -47,6 +47,7 @@ pub enum ConstKind<I: Interner> {
Expr(I::ExprConst),
}
#[cfg(feature = "nightly")]
const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
match value {
Param(_) => 0,
@ -60,7 +61,8 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
}
}
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
#[cfg(feature = "nightly")]
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
where
I::ParamConst: HashStable<CTX>,
I::InferConst: HashStable<CTX>,

View File

@ -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<I: Interner>: TypeVisitable<I> {
/// folders. Do not override this method, to ensure coherence with
/// `try_fold_with`.
fn fold_with<F: TypeFolder<I>>(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<I: Interner>: TypeFoldable<I> {
/// infallible folders. Do not override this method, to ensure coherence
/// with `try_super_fold_with`.
fn super_fold_with<F: TypeFolder<I>>(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<I: Interner>: TypeFoldable<I> {
/// 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<I: Interner>: FallibleTypeFolder<I, Error = !> {
pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = Never> {
fn interner(&self) -> I;
fn fold_binder<T>(&mut self, t: I::Binder<T>) -> I::Binder<T>
@ -208,13 +220,13 @@ impl<I: Interner, F> FallibleTypeFolder<I> for F
where
F: TypeFolder<I>,
{
type Error = !;
type Error = Never;
fn interner(&self) -> I {
TypeFolder::interner(self)
}
fn try_fold_binder<T>(&mut self, t: I::Binder<T>) -> Result<I::Binder<T>, !>
fn try_fold_binder<T>(&mut self, t: I::Binder<T>) -> Result<I::Binder<T>, Never>
where
T: TypeFoldable<I>,
I::Binder<T>: TypeSuperFoldable<I>,
@ -222,25 +234,25 @@ where
Ok(self.fold_binder(t))
}
fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, !>
fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Never>
where
I::Ty: TypeSuperFoldable<I>,
{
Ok(self.fold_ty(t))
}
fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !> {
fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Never> {
Ok(self.fold_region(r))
}
fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, !>
fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Never>
where
I::Const: TypeSuperFoldable<I>,
{
Ok(self.fold_const(c))
}
fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, !>
fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Never>
where
I::Predicate: TypeSuperFoldable<I>,
{
@ -311,7 +323,7 @@ impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Lrc<T> {
// 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

View File

@ -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<T: std::fmt::Write>(
}
}
#[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<A> <: T<B> iff A <: B -- e.g., function return type
Invariant, // T<A> <: T<B> 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 {}
}

View File

@ -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<I: Interner> {
/// Corresponds to `where Foo: Bar<A, B, C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
@ -67,6 +68,7 @@ impl<I: Interner> PartialEq for ClauseKind<I> {
impl<I: Interner> Eq for ClauseKind<I> {}
#[cfg(feature = "nightly")]
fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> usize {
match value {
ClauseKind::Trait(_) => 0,
@ -79,7 +81,8 @@ fn clause_kind_discriminant<I: Interner>(value: &ClauseKind<I>) -> usize {
}
}
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ClauseKind<I>
#[cfg(feature = "nightly")]
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ClauseKind<I>
where
I::Ty: HashStable<CTX>,
I::Const: HashStable<CTX>,
@ -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<I: Interner> {
/// Prove a clause
Clause(ClauseKind<I>),
@ -239,6 +242,7 @@ impl<I: Interner> PartialEq for PredicateKind<I> {
impl<I: Interner> Eq for PredicateKind<I> {}
#[cfg(feature = "nightly")]
fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> usize {
match value {
PredicateKind::Clause(_) => 0,
@ -252,7 +256,8 @@ fn predicate_kind_discriminant<I: Interner>(value: &PredicateKind<I>) -> usize {
}
}
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for PredicateKind<I>
#[cfg(feature = "nightly")]
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for PredicateKind<I>
where
I::DefId: HashStable<CTX>,
I::Const: HashStable<CTX>,
@ -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,

View File

@ -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<I: Interner> {
/// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.
///
@ -261,8 +261,9 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
}
}
#[cfg(feature = "nightly")]
// This is not a derived impl because a derive would require `I: HashStable`
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for RegionKind<I>
where
I::EarlyParamRegion: HashStable<CTX>,
I::BoundRegion: HashStable<CTX>,

View File

@ -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<T> {
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<T> Deref for WithCachedTypeInfo<T> {
impl<T: Hash> Hash for WithCachedTypeInfo<T> {
#[inline]
fn hash<H: Hasher>(&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<T: HashStable<CTX>, CTX> HashStable<CTX> for WithCachedTypeInfo<T> {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
if self.stable_hash == Fingerprint::ZERO || cfg!(debug_assertions) {

View File

@ -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 `<Type as Trait>::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<I: Interner> {
/// The primitive boolean type. Written as `bool`.
Bool,
@ -407,7 +407,7 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
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<I: Interner> DebugWithInfcx<I> for TyKind<I> {
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<I: Interner> DebugWithInfcx<I> for TyKind<I> {
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<I: Interner> DebugWithInfcx<I> for TyKind<I> {
}
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<I: Interner> fmt::Debug for TyKind<I> {
}
// This is not a derived impl because a derive would require `I: HashStable`
#[cfg(feature = "nightly")]
#[allow(rustc::usage_of_ty_tykind)]
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for TyKind<I>
where
I::AdtDef: HashStable<CTX>,
I::DefId: HashStable<CTX>,
@ -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<IntVarValue>;
#[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<FloatVarValue>;
#[inline]
@ -835,10 +847,11 @@ impl UnifyKey for FloatVid {
}
}
#[cfg(feature = "nightly")]
impl<CTX> HashStable<CTX> 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:?}")

View File

@ -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<I: Interner>: TypeVisitable<I> {
/// 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<I: Interner>: Sized {
#[cfg(feature = "nightly")]
type BreakTy = !;
#[cfg(not(feature = "nightly"))]
type BreakTy;
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
where
I::Binder<T>: TypeSuperVisitable<I>,