mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Begin nightly-ifying rustc_type_ir
This commit is contained in:
parent
2831701757
commit
4506681e2f
11
Cargo.lock
11
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"
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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 {}
|
||||
}
|
||||
|
17
compiler/rustc_index_macros/Cargo.toml
Normal file
17
compiler/rustc_index_macros/Cargo.toml
Normal 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 = []
|
30
compiler/rustc_index_macros/src/lib.rs
Normal file
30
compiler/rustc_index_macros/src/lib.rs
Normal 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)
|
||||
}
|
@ -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,
|
||||
}
|
@ -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)] =>
|
||||
|
@ -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::*;
|
||||
|
@ -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",
|
||||
]
|
||||
|
@ -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>,
|
||||
{
|
||||
|
@ -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>,
|
||||
|
@ -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
|
||||
|
@ -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 {}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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>,
|
||||
|
@ -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) {
|
||||
|
@ -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:?}")
|
||||
|
@ -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>,
|
||||
|
Loading…
Reference in New Issue
Block a user