Skip to content

Commit

Permalink
Begin nightly-ifying rustc_type_ir
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 24, 2023
1 parent cee6db1 commit 9b2792d
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 93 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4005,11 +4005,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 0.13.0",
]

[[package]]
name = "rustc_infer"
version = "0.0.0"
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_index/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ edition = "2021"
[dependencies]
arrayvec = { version = "0.7", default-features = false }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_index_macros = { path = "../rustc_index_macros", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
smallvec = "1.8.1"

[features]
default = ["nightly"]
nightly = ["rustc_serialize", "rustc_macros"]
nightly = ["rustc_serialize", "rustc_macros", "rustc_index_macros/nightly"]
3 changes: 1 addition & 2 deletions compiler/rustc_index/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_index/src/vec/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,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 {}
}
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_index_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions compiler/rustc_index_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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> {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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,
}
Expand Down
22 changes: 0 additions & 22 deletions compiler/rustc_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use proc_macro::TokenStream;
mod diagnostics;
mod hash_stable;
mod lift;
mod newtype;
mod query;
mod serialize;
mod symbols;
Expand All @@ -34,27 +33,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)] =>
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet;
use rustc_index::newtype_index;
use rustc_index::IndexVec;
use rustc_macros::newtype_index;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
Expand Down
21 changes: 16 additions & 5 deletions compiler/rustc_type_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@ edition = "2021"

[dependencies]
bitflags = "1.2.1"
rustc_index = { path = "../rustc_index" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_macros = { path = "../rustc_macros" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_macros = { path = "../rustc_macros", optional = true }
smallvec = { version = "1.8.1" }

[features]
default = ["nightly"]
nightly = [
"smallvec/may_dangle",
"smallvec/union",
"rustc_index/nightly",
"rustc_serialize",
"rustc_data_structures",
"rustc_macros",
]
12 changes: 8 additions & 4 deletions compiler/rustc_type_ir/src/const_kind.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#[cfg(feature = "nightly")]
use rustc_data_structures::stable_hasher::HashStable;
#[cfg(feature = "nightly")]
use rustc_serialize::{Decodable, Decoder, Encodable};
use std::cmp::Ordering;
use std::fmt;
use std::hash;

use crate::{
DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, OptWithInfcx,
TyDecoder, TyEncoder,
};
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, OptWithInfcx};
#[cfg(feature = "nightly")]
use crate::{HashStableContext, TyDecoder, TyEncoder};

use self::ConstKind::*;

Expand Down Expand Up @@ -75,6 +76,7 @@ impl<I: Interner> hash::Hash for ConstKind<I> {
}
}

#[cfg(feature = "nightly")]
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
where
I::ParamConst: HashStable<CTX>,
Expand Down Expand Up @@ -108,6 +110,7 @@ where
}
}

#[cfg(feature = "nightly")]
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for ConstKind<I>
where
I::ParamConst: Decodable<D>,
Expand Down Expand Up @@ -140,6 +143,7 @@ where
}
}

#[cfg(feature = "nightly")]
impl<I: Interner, E: TyEncoder<I = I>> Encodable<E> for ConstKind<I>
where
I::ParamConst: Encodable<E>,
Expand Down
34 changes: 23 additions & 11 deletions compiler/rustc_type_ir/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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 {},
}
}
}

Expand All @@ -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 {},
}
}
}

Expand All @@ -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>
Expand Down Expand Up @@ -208,39 +220,39 @@ 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>,
{
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>,
{
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 9b2792d

Please sign in to comment.