Skip to content

Commit

Permalink
Use min_specialization in the remaining rustc crates
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewjasper committed Jun 10, 2020
1 parent feb3536 commit 88ea7e5
Show file tree
Hide file tree
Showing 22 changed files with 373 additions and 248 deletions.
29 changes: 19 additions & 10 deletions src/librustc_arena/lib.rs
Expand Up @@ -610,7 +610,7 @@ macro_rules! which_arena_for_type {

#[macro_export]
macro_rules! declare_arena {
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
([], [$($a:tt $name:ident: $ty:ty, $gen_ty:ty;)*], $tcx:lifetime) => {
#[derive(Default)]
pub struct Arena<$tcx> {
pub dropless: $crate::DroplessArena,
Expand All @@ -619,17 +619,17 @@ macro_rules! declare_arena {
}

#[marker]
pub trait ArenaAllocatable {}
pub trait ArenaAllocatable<'tcx> {}

impl<T: Copy> ArenaAllocatable for T {}
impl<'tcx, T: Copy> ArenaAllocatable<'tcx> for T {}

unsafe trait ArenaField<'tcx>: Sized {
unsafe trait ArenaField<'tcx>: Sized + ArenaAllocatable<'tcx> {
/// Returns a specific arena to allocate from.
/// If `None` is returned, the `DropArena` will be used.
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>>;
}

unsafe impl<'tcx, T> ArenaField<'tcx> for T {
unsafe impl<'tcx, T: ArenaAllocatable<'tcx>> ArenaField<'tcx> for T {
#[inline]
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> {
panic!()
Expand All @@ -638,18 +638,27 @@ macro_rules! declare_arena {

$(
#[allow(unused_lifetimes)]
impl<$tcx> ArenaAllocatable for $ty {}
unsafe impl<$tcx> ArenaField<$tcx> for $ty {
impl<$tcx> ArenaAllocatable<$tcx> for $ty {}
unsafe impl<$tcx, '_x, '_y, '_z, '_w> ArenaField<$tcx> for $gen_ty where Self: ArenaAllocatable<$tcx> {
#[inline]
fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena<Self>> {
$crate::which_arena_for_type!($a[&_arena.$name])
// SAFETY: We only implement `ArenaAllocatable<$tcx>` for
// `$ty`, so `$ty` and Self are the same type
unsafe {
::std::mem::transmute::<
Option<&'a $crate::TypedArena<$ty>>,
Option<&'a $crate::TypedArena<Self>>,
>(
$crate::which_arena_for_type!($a[&_arena.$name])
)
}
}
}
)*

impl<'tcx> Arena<'tcx> {
#[inline]
pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
pub fn alloc<T: ArenaAllocatable<'tcx>>(&self, value: T) -> &mut T {
if !::std::mem::needs_drop::<T>() {
return self.dropless.alloc(value);
}
Expand All @@ -667,7 +676,7 @@ macro_rules! declare_arena {
self.dropless.alloc_slice(value)
}

pub fn alloc_from_iter<'a, T: ArenaAllocatable>(
pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx>>(
&'a self,
iter: impl ::std::iter::IntoIterator<Item = T>,
) -> &'a mut [T] {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_ast_lowering/lib.rs
Expand Up @@ -33,7 +33,7 @@
#![feature(array_value_iter)]
#![feature(crate_visibility_modifier)]
#![feature(marker_trait_attr)]
#![feature(specialization)] // FIXME: min_specialization does not work
#![feature(min_specialization)]
#![feature(or_patterns)]
#![recursion_limit = "256"]

Expand Down
70 changes: 35 additions & 35 deletions src/librustc_hir/arena.rs
Expand Up @@ -12,41 +12,41 @@ macro_rules! arena_types {
($macro:path, $args:tt, $tcx:lifetime) => (
$macro!($args, [
// HIR types
[few] hir_krate: rustc_hir::Crate<$tcx>,
[] arm: rustc_hir::Arm<$tcx>,
[] asm_operand: rustc_hir::InlineAsmOperand<$tcx>,
[] asm_template: rustc_ast::ast::InlineAsmTemplatePiece,
[] attribute: rustc_ast::ast::Attribute,
[] block: rustc_hir::Block<$tcx>,
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
[few] global_asm: rustc_hir::GlobalAsm,
[] generic_arg: rustc_hir::GenericArg<$tcx>,
[] generic_args: rustc_hir::GenericArgs<$tcx>,
[] generic_bound: rustc_hir::GenericBound<$tcx>,
[] generic_param: rustc_hir::GenericParam<$tcx>,
[] expr: rustc_hir::Expr<$tcx>,
[] field: rustc_hir::Field<$tcx>,
[] field_pat: rustc_hir::FieldPat<$tcx>,
[] fn_decl: rustc_hir::FnDecl<$tcx>,
[] foreign_item: rustc_hir::ForeignItem<$tcx>,
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
[few] inline_asm: rustc_hir::InlineAsm<$tcx>,
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
[] local: rustc_hir::Local<$tcx>,
[few] macro_def: rustc_hir::MacroDef<$tcx>,
[] param: rustc_hir::Param<$tcx>,
[] pat: rustc_hir::Pat<$tcx>,
[] path: rustc_hir::Path<$tcx>,
[] path_segment: rustc_hir::PathSegment<$tcx>,
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
[] qpath: rustc_hir::QPath<$tcx>,
[] stmt: rustc_hir::Stmt<$tcx>,
[] struct_field: rustc_hir::StructField<$tcx>,
[] trait_item_ref: rustc_hir::TraitItemRef,
[] ty: rustc_hir::Ty<$tcx>,
[] type_binding: rustc_hir::TypeBinding<$tcx>,
[] variant: rustc_hir::Variant<$tcx>,
[] where_predicate: rustc_hir::WherePredicate<$tcx>,
[few] hir_krate: rustc_hir::Crate<$tcx>, rustc_hir::Crate<'_x>;
[] arm: rustc_hir::Arm<$tcx>, rustc_hir::Arm<'_x>;
[] asm_operand: rustc_hir::InlineAsmOperand<$tcx>, rustc_hir::InlineAsmOperand<'_x>;
[] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, rustc_ast::ast::InlineAsmTemplatePiece;
[] attribute: rustc_ast::ast::Attribute, rustc_ast::ast::Attribute;
[] block: rustc_hir::Block<$tcx>, rustc_hir::Block<'_x>;
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>, rustc_hir::BareFnTy<'_x>;
[few] global_asm: rustc_hir::GlobalAsm, rustc_hir::GlobalAsm;
[] generic_arg: rustc_hir::GenericArg<$tcx>, rustc_hir::GenericArg<'_x>;
[] generic_args: rustc_hir::GenericArgs<$tcx>, rustc_hir::GenericArgs<'_x>;
[] generic_bound: rustc_hir::GenericBound<$tcx>, rustc_hir::GenericBound<'_x>;
[] generic_param: rustc_hir::GenericParam<$tcx>, rustc_hir::GenericParam<'_x>;
[] expr: rustc_hir::Expr<$tcx>, rustc_hir::Expr<'_x>;
[] field: rustc_hir::Field<$tcx>, rustc_hir::Field<'_x>;
[] field_pat: rustc_hir::FieldPat<$tcx>, rustc_hir::FieldPat<'_x>;
[] fn_decl: rustc_hir::FnDecl<$tcx>, rustc_hir::FnDecl<'_x>;
[] foreign_item: rustc_hir::ForeignItem<$tcx>, rustc_hir::ForeignItem<'_x>;
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>, rustc_hir::ImplItemRef<'_x>;
[few] inline_asm: rustc_hir::InlineAsm<$tcx>, rustc_hir::InlineAsm<'_x>;
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, rustc_hir::LlvmInlineAsm<'_x>;
[] local: rustc_hir::Local<$tcx>, rustc_hir::Local<'_x>;
[few] macro_def: rustc_hir::MacroDef<$tcx>, rustc_hir::MacroDef<'_x>;
[] param: rustc_hir::Param<$tcx>, rustc_hir::Param<'_x>;
[] pat: rustc_hir::Pat<$tcx>, rustc_hir::Pat<'_x>;
[] path: rustc_hir::Path<$tcx>, rustc_hir::Path<'_x>;
[] path_segment: rustc_hir::PathSegment<$tcx>, rustc_hir::PathSegment<'_x>;
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>, rustc_hir::PolyTraitRef<'_x>;
[] qpath: rustc_hir::QPath<$tcx>, rustc_hir::QPath<'_x>;
[] stmt: rustc_hir::Stmt<$tcx>, rustc_hir::Stmt<'_x>;
[] struct_field: rustc_hir::StructField<$tcx>, rustc_hir::StructField<'_x>;
[] trait_item_ref: rustc_hir::TraitItemRef, rustc_hir::TraitItemRef;
[] ty: rustc_hir::Ty<$tcx>, rustc_hir::Ty<'_x>;
[] type_binding: rustc_hir::TypeBinding<$tcx>, rustc_hir::TypeBinding<'_x>;
[] variant: rustc_hir::Variant<$tcx>, rustc_hir::Variant<'_x>;
[] where_predicate: rustc_hir::WherePredicate<$tcx>, rustc_hir::WherePredicate<'_x>;
], $tcx);
)
}
2 changes: 1 addition & 1 deletion src/librustc_infer/infer/canonical/query_response.rs
Expand Up @@ -56,7 +56,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
) -> Fallible<CanonicalizedQueryResponse<'tcx, T>>
where
T: Debug + TypeFoldable<'tcx>,
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable,
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
{
let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
let canonical_result = self.canonicalize_response(&query_response);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_macros/src/query.rs
Expand Up @@ -433,7 +433,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {

try_load_from_on_disk_cache_stream.extend(quote! {
::rustc_middle::dep_graph::DepKind::#name => {
if <#arg as DepNodeParams<TyCtxt<'_>>>::CAN_RECONSTRUCT_QUERY_KEY {
if <#arg as DepNodeParams<TyCtxt<'_>>>::can_reconstruct_query_key() {
debug_assert!($tcx.dep_graph
.node_color($dep_node)
.map(|c| c.is_green())
Expand Down Expand Up @@ -490,7 +490,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
// Add a match arm to force the query given the dep node
dep_node_force_stream.extend(quote! {
::rustc_middle::dep_graph::DepKind::#name => {
if <#arg as DepNodeParams<TyCtxt<'_>>>::CAN_RECONSTRUCT_QUERY_KEY {
if <#arg as DepNodeParams<TyCtxt<'_>>>::can_reconstruct_query_key() {
if let Some(key) = <#arg as DepNodeParams<TyCtxt<'_>>>::recover($tcx, $dep_node) {
force_query::<crate::ty::query::queries::#name<'_>, _>(
$tcx,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_metadata/lib.rs
Expand Up @@ -7,7 +7,7 @@
#![feature(nll)]
#![feature(or_patterns)]
#![feature(proc_macro_internals)]
#![feature(specialization)] // FIXME: min_specialization ICEs
#![feature(min_specialization)]
#![feature(stmt_expr_attributes)]
#![recursion_limit = "256"]

Expand Down
17 changes: 9 additions & 8 deletions src/librustc_metadata/rmeta/decoder.rs
Expand Up @@ -30,7 +30,7 @@ use rustc_middle::mir::{self, interpret, Body, Promoted};
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util::common::record_time;
use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder};
use rustc_serialize::{opaque, Decodable, Decoder, SpecializedDecoder, UseSpecializedDecodable};
use rustc_session::Session;
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{sym, Ident, Symbol};
Expand Down Expand Up @@ -218,15 +218,15 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadataRef<'a>, TyCtxt<'tcx>) {
}
}

impl<'a, 'tcx, T: Decodable> Lazy<T> {
impl<'a, 'tcx, T: Decodable> Lazy<T, ()> {
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
T::decode(&mut dcx).unwrap()
}
}

impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> {
impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T], usize> {
fn decode<M: Metadata<'a, 'tcx>>(
self,
metadata: M,
Expand Down Expand Up @@ -321,20 +321,20 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
}
}

impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T, ()>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
self.read_lazy_with_meta(())
}
}

impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T], usize>> for DecodeContext<'a, 'tcx> {
fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
let len = self.read_usize()?;
if len == 0 { Ok(Lazy::empty()) } else { self.read_lazy_with_meta(len) }
}
}

impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>>> for DecodeContext<'a, 'tcx>
impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>, usize>> for DecodeContext<'a, 'tcx>
where
Option<T>: FixedSizeEncoding,
{
Expand Down Expand Up @@ -515,8 +515,9 @@ impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
}
}

impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
for DecodeContext<'a, 'tcx>
impl<'a, 'tcx, T> SpecializedDecoder<mir::ClearCrossCrate<T>> for DecodeContext<'a, 'tcx>
where
mir::ClearCrossCrate<T>: UseSpecializedDecodable,
{
#[inline]
fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
Expand Down
35 changes: 25 additions & 10 deletions src/librustc_metadata/rmeta/encoder.rs
Expand Up @@ -27,7 +27,7 @@ use rustc_middle::mir::{self, interpret};
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::{self as ty_codec, TyEncoder};
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder, UseSpecializedEncodable};
use rustc_session::config::CrateType;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
Expand Down Expand Up @@ -93,13 +93,13 @@ impl<'tcx> Encoder for EncodeContext<'tcx> {
}
}

impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
impl<'tcx, T> SpecializedEncoder<Lazy<T, ()>> for EncodeContext<'tcx> {
fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
self.emit_lazy_distance(*lazy)
}
}

impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
impl<'tcx, T> SpecializedEncoder<Lazy<[T], usize>> for EncodeContext<'tcx> {
fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
self.emit_usize(lazy.meta)?;
if lazy.meta == 0 {
Expand All @@ -109,7 +109,7 @@ impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
}
}

impl<'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>>> for EncodeContext<'tcx>
impl<'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>, usize>> for EncodeContext<'tcx>
where
Option<T>: FixedSizeEncoding,
{
Expand Down Expand Up @@ -228,8 +228,13 @@ impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
}
}

impl<'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'tcx> {
fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> {
impl<'a, 'b, 'tcx> SpecializedEncoder<&'a ty::TyS<'b>> for EncodeContext<'tcx>
where
&'a ty::TyS<'b>: UseSpecializedEncodable,
{
fn specialized_encode(&mut self, ty: &&'a ty::TyS<'b>) -> Result<(), Self::Error> {
debug_assert!(self.tcx.lift(ty).is_some());
let ty = unsafe { std::mem::transmute::<&&'a ty::TyS<'b>, &&'tcx ty::TyS<'tcx>>(ty) };
ty_codec::encode_with_shorthand(self, ty, |ecx| &mut ecx.type_shorthands)
}
}
Expand All @@ -251,12 +256,19 @@ impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
}
}

impl<'tcx> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> for EncodeContext<'tcx> {
impl<'a, 'b, 'tcx> SpecializedEncoder<&'a [(ty::Predicate<'b>, Span)]> for EncodeContext<'tcx> {
fn specialized_encode(
&mut self,
predicates: &&'tcx [(ty::Predicate<'tcx>, Span)],
predicates: &&'a [(ty::Predicate<'b>, Span)],
) -> Result<(), Self::Error> {
ty_codec::encode_spanned_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands)
debug_assert!(self.tcx.lift(*predicates).is_some());
let predicates = unsafe {
std::mem::transmute::<
&&'a [(ty::Predicate<'b>, Span)],
&&'tcx [(ty::Predicate<'tcx>, Span)],
>(predicates)
};
ty_codec::encode_spanned_predicates(self, &predicates, |ecx| &mut ecx.predicate_shorthands)
}
}

Expand All @@ -266,7 +278,10 @@ impl<'tcx> SpecializedEncoder<Fingerprint> for EncodeContext<'tcx> {
}
}

impl<'tcx, T: Encodable> SpecializedEncoder<mir::ClearCrossCrate<T>> for EncodeContext<'tcx> {
impl<'tcx, T> SpecializedEncoder<mir::ClearCrossCrate<T>> for EncodeContext<'tcx>
where
mir::ClearCrossCrate<T>: UseSpecializedEncodable,
{
fn specialized_encode(&mut self, _: &mir::ClearCrossCrate<T>) -> Result<(), Self::Error> {
Ok(())
}
Expand Down

0 comments on commit 88ea7e5

Please sign in to comment.