未验证 提交 eef9356e 编写于 作者: R Ralf Jung 提交者: GitHub

Rollup merge of #72707 - matthewjasper:rustc_min_spec, r=oli-obk

Use min_specialization in the remaining rustc crates

This adds a lot of `transmute` calls to replace the unsound uses of specialization.
It's ugly, but at least it's honest about what's going on.

cc #71420, @RalfJung
...@@ -602,7 +602,7 @@ pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> & ...@@ -602,7 +602,7 @@ pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &
#[macro_export] #[macro_export]
macro_rules! declare_arena { 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)] #[derive(Default)]
pub struct Arena<$tcx> { pub struct Arena<$tcx> {
pub dropless: $crate::DroplessArena, pub dropless: $crate::DroplessArena,
...@@ -611,17 +611,17 @@ pub struct Arena<$tcx> { ...@@ -611,17 +611,17 @@ pub struct Arena<$tcx> {
} }
#[marker] #[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. /// Returns a specific arena to allocate from.
/// If `None` is returned, the `DropArena` will be used. /// If `None` is returned, the `DropArena` will be used.
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>>; 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] #[inline]
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> { default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> {
panic!() panic!()
...@@ -630,18 +630,27 @@ unsafe impl<'tcx, T> ArenaField<'tcx> for T { ...@@ -630,18 +630,27 @@ unsafe impl<'tcx, T> ArenaField<'tcx> for T {
$( $(
#[allow(unused_lifetimes)] #[allow(unused_lifetimes)]
impl<$tcx> ArenaAllocatable for $ty {} impl<$tcx> ArenaAllocatable<$tcx> for $ty {}
unsafe impl<$tcx> ArenaField<$tcx> for $ty { unsafe impl<$tcx, '_x, '_y, '_z, '_w> ArenaField<$tcx> for $gen_ty where Self: ArenaAllocatable<$tcx> {
#[inline] #[inline]
fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena<Self>> { 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> { impl<'tcx> Arena<'tcx> {
#[inline] #[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>() { if !::std::mem::needs_drop::<T>() {
return self.dropless.alloc(value); return self.dropless.alloc(value);
} }
...@@ -659,7 +668,7 @@ pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] { ...@@ -659,7 +668,7 @@ pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] {
self.dropless.alloc_slice(value) self.dropless.alloc_slice(value)
} }
pub fn alloc_from_iter<'a, T: ArenaAllocatable>( pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx>>(
&'a self, &'a self,
iter: impl ::std::iter::IntoIterator<Item = T>, iter: impl ::std::iter::IntoIterator<Item = T>,
) -> &'a mut [T] { ) -> &'a mut [T] {
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#![feature(array_value_iter)] #![feature(array_value_iter)]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(marker_trait_attr)] #![feature(marker_trait_attr)]
#![feature(specialization)] // FIXME: min_specialization does not work #![feature(min_specialization)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
......
...@@ -12,41 +12,41 @@ ...@@ -12,41 +12,41 @@
($macro:path, $args:tt, $tcx:lifetime) => ( ($macro:path, $args:tt, $tcx:lifetime) => (
$macro!($args, [ $macro!($args, [
// HIR types // HIR types
[few] hir_krate: rustc_hir::Crate<$tcx>, [few] hir_krate: rustc_hir::Crate<$tcx>, rustc_hir::Crate<'_x>;
[] arm: rustc_hir::Arm<$tcx>, [] arm: rustc_hir::Arm<$tcx>, rustc_hir::Arm<'_x>;
[] asm_operand: rustc_hir::InlineAsmOperand<$tcx>, [] asm_operand: rustc_hir::InlineAsmOperand<$tcx>, rustc_hir::InlineAsmOperand<'_x>;
[] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, [] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, rustc_ast::ast::InlineAsmTemplatePiece;
[] attribute: rustc_ast::ast::Attribute, [] attribute: rustc_ast::ast::Attribute, rustc_ast::ast::Attribute;
[] block: rustc_hir::Block<$tcx>, [] block: rustc_hir::Block<$tcx>, rustc_hir::Block<'_x>;
[] bare_fn_ty: rustc_hir::BareFnTy<$tcx>, [] bare_fn_ty: rustc_hir::BareFnTy<$tcx>, rustc_hir::BareFnTy<'_x>;
[few] global_asm: rustc_hir::GlobalAsm, [few] global_asm: rustc_hir::GlobalAsm, rustc_hir::GlobalAsm;
[] generic_arg: rustc_hir::GenericArg<$tcx>, [] generic_arg: rustc_hir::GenericArg<$tcx>, rustc_hir::GenericArg<'_x>;
[] generic_args: rustc_hir::GenericArgs<$tcx>, [] generic_args: rustc_hir::GenericArgs<$tcx>, rustc_hir::GenericArgs<'_x>;
[] generic_bound: rustc_hir::GenericBound<$tcx>, [] generic_bound: rustc_hir::GenericBound<$tcx>, rustc_hir::GenericBound<'_x>;
[] generic_param: rustc_hir::GenericParam<$tcx>, [] generic_param: rustc_hir::GenericParam<$tcx>, rustc_hir::GenericParam<'_x>;
[] expr: rustc_hir::Expr<$tcx>, [] expr: rustc_hir::Expr<$tcx>, rustc_hir::Expr<'_x>;
[] field: rustc_hir::Field<$tcx>, [] field: rustc_hir::Field<$tcx>, rustc_hir::Field<'_x>;
[] field_pat: rustc_hir::FieldPat<$tcx>, [] field_pat: rustc_hir::FieldPat<$tcx>, rustc_hir::FieldPat<'_x>;
[] fn_decl: rustc_hir::FnDecl<$tcx>, [] fn_decl: rustc_hir::FnDecl<$tcx>, rustc_hir::FnDecl<'_x>;
[] foreign_item: rustc_hir::ForeignItem<$tcx>, [] foreign_item: rustc_hir::ForeignItem<$tcx>, rustc_hir::ForeignItem<'_x>;
[] impl_item_ref: rustc_hir::ImplItemRef<$tcx>, [] impl_item_ref: rustc_hir::ImplItemRef<$tcx>, rustc_hir::ImplItemRef<'_x>;
[few] inline_asm: rustc_hir::InlineAsm<$tcx>, [few] inline_asm: rustc_hir::InlineAsm<$tcx>, rustc_hir::InlineAsm<'_x>;
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, [few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>, rustc_hir::LlvmInlineAsm<'_x>;
[] local: rustc_hir::Local<$tcx>, [] local: rustc_hir::Local<$tcx>, rustc_hir::Local<'_x>;
[few] macro_def: rustc_hir::MacroDef<$tcx>, [few] macro_def: rustc_hir::MacroDef<$tcx>, rustc_hir::MacroDef<'_x>;
[] param: rustc_hir::Param<$tcx>, [] param: rustc_hir::Param<$tcx>, rustc_hir::Param<'_x>;
[] pat: rustc_hir::Pat<$tcx>, [] pat: rustc_hir::Pat<$tcx>, rustc_hir::Pat<'_x>;
[] path: rustc_hir::Path<$tcx>, [] path: rustc_hir::Path<$tcx>, rustc_hir::Path<'_x>;
[] path_segment: rustc_hir::PathSegment<$tcx>, [] path_segment: rustc_hir::PathSegment<$tcx>, rustc_hir::PathSegment<'_x>;
[] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>, [] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>, rustc_hir::PolyTraitRef<'_x>;
[] qpath: rustc_hir::QPath<$tcx>, [] qpath: rustc_hir::QPath<$tcx>, rustc_hir::QPath<'_x>;
[] stmt: rustc_hir::Stmt<$tcx>, [] stmt: rustc_hir::Stmt<$tcx>, rustc_hir::Stmt<'_x>;
[] struct_field: rustc_hir::StructField<$tcx>, [] struct_field: rustc_hir::StructField<$tcx>, rustc_hir::StructField<'_x>;
[] trait_item_ref: rustc_hir::TraitItemRef, [] trait_item_ref: rustc_hir::TraitItemRef, rustc_hir::TraitItemRef;
[] ty: rustc_hir::Ty<$tcx>, [] ty: rustc_hir::Ty<$tcx>, rustc_hir::Ty<'_x>;
[] type_binding: rustc_hir::TypeBinding<$tcx>, [] type_binding: rustc_hir::TypeBinding<$tcx>, rustc_hir::TypeBinding<'_x>;
[] variant: rustc_hir::Variant<$tcx>, [] variant: rustc_hir::Variant<$tcx>, rustc_hir::Variant<'_x>;
[] where_predicate: rustc_hir::WherePredicate<$tcx>, [] where_predicate: rustc_hir::WherePredicate<$tcx>, rustc_hir::WherePredicate<'_x>;
], $tcx); ], $tcx);
) )
} }
...@@ -56,7 +56,7 @@ pub fn make_canonicalized_query_response<T>( ...@@ -56,7 +56,7 @@ pub fn make_canonicalized_query_response<T>(
) -> Fallible<CanonicalizedQueryResponse<'tcx, T>> ) -> Fallible<CanonicalizedQueryResponse<'tcx, T>>
where where
T: Debug + TypeFoldable<'tcx>, 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 query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
let canonical_result = self.canonicalize_response(&query_response); let canonical_result = self.canonicalize_response(&query_response);
......
...@@ -433,7 +433,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { ...@@ -433,7 +433,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
try_load_from_on_disk_cache_stream.extend(quote! { try_load_from_on_disk_cache_stream.extend(quote! {
::rustc_middle::dep_graph::DepKind::#name => { ::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 debug_assert!($tcx.dep_graph
.node_color($dep_node) .node_color($dep_node)
.map(|c| c.is_green()) .map(|c| c.is_green())
...@@ -490,7 +490,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { ...@@ -490,7 +490,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream {
// Add a match arm to force the query given the dep node // Add a match arm to force the query given the dep node
dep_node_force_stream.extend(quote! { dep_node_force_stream.extend(quote! {
::rustc_middle::dep_graph::DepKind::#name => { ::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) { if let Some(key) = <#arg as DepNodeParams<TyCtxt<'_>>>::recover($tcx, $dep_node) {
force_query::<crate::ty::query::queries::#name<'_>, _>( force_query::<crate::ty::query::queries::#name<'_>, _>(
$tcx, $tcx,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#![feature(nll)] #![feature(nll)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(proc_macro_internals)] #![feature(proc_macro_internals)]
#![feature(specialization)] // FIXME: min_specialization ICEs #![feature(min_specialization)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
#![recursion_limit = "256"] #![recursion_limit = "256"]
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util::common::record_time; 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_session::Session;
use rustc_span::source_map::{respan, Spanned}; use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::symbol::{sym, Ident, Symbol};
...@@ -218,7 +218,7 @@ fn tcx(self) -> Option<TyCtxt<'tcx>> { ...@@ -218,7 +218,7 @@ fn tcx(self) -> Option<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 { fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
let mut dcx = metadata.decoder(self.position.get()); let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position); dcx.lazy_state = LazyState::NodeStart(self.position);
...@@ -226,7 +226,7 @@ fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T { ...@@ -226,7 +226,7 @@ fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
} }
} }
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>>( fn decode<M: Metadata<'a, 'tcx>>(
self, self,
metadata: M, metadata: M,
...@@ -321,20 +321,20 @@ fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { ...@@ -321,20 +321,20 @@ fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
} }
} }
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> { fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
self.read_lazy_with_meta(()) 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> { fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
let len = self.read_usize()?; let len = self.read_usize()?;
if len == 0 { Ok(Lazy::empty()) } else { self.read_lazy_with_meta(len) } 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 where
Option<T>: FixedSizeEncoding, Option<T>: FixedSizeEncoding,
{ {
...@@ -515,8 +515,9 @@ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> { ...@@ -515,8 +515,9 @@ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
} }
} }
impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>> impl<'a, 'tcx, T> SpecializedDecoder<mir::ClearCrossCrate<T>> for DecodeContext<'a, 'tcx>
for DecodeContext<'a, 'tcx> where
mir::ClearCrossCrate<T>: UseSpecializedDecodable,
{ {
#[inline] #[inline]
fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> { fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
use rustc_middle::traits::specialization_graph; use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::{self as ty_codec, TyEncoder}; use rustc_middle::ty::codec::{self as ty_codec, TyEncoder};
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt}; 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_session::config::CrateType;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
...@@ -93,13 +93,13 @@ fn emit_unit(&mut self) -> Result<(), Self::Error> { ...@@ -93,13 +93,13 @@ fn emit_unit(&mut self) -> Result<(), Self::Error> {
} }
} }
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> { fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
self.emit_lazy_distance(*lazy) 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> { fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
self.emit_usize(lazy.meta)?; self.emit_usize(lazy.meta)?;
if lazy.meta == 0 { if lazy.meta == 0 {
...@@ -109,7 +109,7 @@ fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> { ...@@ -109,7 +109,7 @@ fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
} }
} }
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 where
Option<T>: FixedSizeEncoding, Option<T>: FixedSizeEncoding,
{ {
...@@ -228,8 +228,13 @@ fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> ...@@ -228,8 +228,13 @@ fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error>
} }
} }
impl<'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'tcx> { impl<'a, 'b, 'tcx> SpecializedEncoder<&'a ty::TyS<'b>> for EncodeContext<'tcx>
fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> { 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) ty_codec::encode_with_shorthand(self, ty, |ecx| &mut ecx.type_shorthands)
} }
} }
...@@ -251,12 +256,19 @@ fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Se ...@@ -251,12 +256,19 @@ fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Se
} }
} }
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( fn specialized_encode(
&mut self, &mut self,
predicates: &&'tcx [(ty::Predicate<'tcx>, Span)], predicates: &&'a [(ty::Predicate<'b>, Span)],
) -> Result<(), Self::Error> { ) -> 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)
} }
} }
...@@ -266,7 +278,10 @@ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { ...@@ -266,7 +278,10 @@ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
} }
} }
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> { fn specialized_encode(&mut self, _: &mir::ClearCrossCrate<T>) -> Result<(), Self::Error> {
Ok(()) Ok(())
} }
......
...@@ -11,79 +11,109 @@ ...@@ -11,79 +11,109 @@
macro_rules! arena_types { macro_rules! arena_types {
($macro:path, $args:tt, $tcx:lifetime) => ( ($macro:path, $args:tt, $tcx:lifetime) => (
$macro!($args, [ $macro!($args, [
[] layouts: rustc_target::abi::Layout, [] layouts: rustc_target::abi::Layout, rustc_target::abi::Layout;
// AdtDef are interned and compared by address // AdtDef are interned and compared by address
[] adt_def: rustc_middle::ty::AdtDef, [] adt_def: rustc_middle::ty::AdtDef, rustc_middle::ty::AdtDef;
[decode] tables: rustc_middle::ty::TypeckTables<$tcx>, [decode] tables: rustc_middle::ty::TypeckTables<$tcx>, rustc_middle::ty::TypeckTables<'_x>;
[] const_allocs: rustc_middle::mir::interpret::Allocation, [] const_allocs: rustc_middle::mir::interpret::Allocation, rustc_middle::mir::interpret::Allocation;
// Required for the incremental on-disk cache // Required for the incremental on-disk cache
[few, decode] mir_keys: rustc_hir::def_id::DefIdSet, [few, decode] mir_keys: rustc_hir::def_id::DefIdSet, rustc_hir::def_id::DefIdSet;
[] region_scope_tree: rustc_middle::middle::region::ScopeTree, [] region_scope_tree: rustc_middle::middle::region::ScopeTree, rustc_middle::middle::region::ScopeTree;
[] dropck_outlives: [] dropck_outlives:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx,
rustc_middle::traits::query::DropckOutlivesResult<'tcx> rustc_middle::traits::query::DropckOutlivesResult<'tcx>
> >
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y,
rustc_middle::traits::query::DropckOutlivesResult<'_z>
>
>;
[] normalize_projection_ty: [] normalize_projection_ty:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx,
rustc_middle::traits::query::NormalizationResult<'tcx> rustc_middle::traits::query::NormalizationResult<'tcx>
> >
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y,
rustc_middle::traits::query::NormalizationResult<'_z>
>
>;
[] implied_outlives_bounds: [] implied_outlives_bounds:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::infer::canonical::QueryResponse<'tcx,
Vec<rustc_middle::traits::query::OutlivesBound<'tcx>> Vec<rustc_middle::traits::query::OutlivesBound<'tcx>>
> >
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y,
Vec<rustc_middle::traits::query::OutlivesBound<'_z>>
>
>;
[] type_op_subtype: [] type_op_subtype:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, ()> rustc_middle::infer::canonical::QueryResponse<'tcx, ()>
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y, ()>
>;
[] type_op_normalize_poly_fn_sig: [] type_op_normalize_poly_fn_sig:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>> rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::PolyFnSig<'tcx>>
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y, rustc_middle::ty::PolyFnSig<'_z>>
>;
[] type_op_normalize_fn_sig: [] type_op_normalize_fn_sig:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>> rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::FnSig<'tcx>>
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y, rustc_middle::ty::FnSig<'_z>>
>;
[] type_op_normalize_predicate: [] type_op_normalize_predicate:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Predicate<'tcx>> rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Predicate<'tcx>>
>, >,
rustc_middle::infer::canonical::Canonical<'_x,
rustc_middle::infer::canonical::QueryResponse<'_y, rustc_middle::ty::Predicate<'_z>>
>;
[] type_op_normalize_ty: [] type_op_normalize_ty:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>> rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>>
>, >,
[few] all_traits: Vec<rustc_hir::def_id::DefId>, rustc_middle::infer::canonical::Canonical<'_x,
[few] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, rustc_middle::infer::canonical::QueryResponse<'_y, &'_z rustc_middle::ty::TyS<'_w>>
[few] foreign_module: rustc_middle::middle::cstore::ForeignModule, >;
[few] foreign_modules: Vec<rustc_middle::middle::cstore::ForeignModule>, [few] all_traits: Vec<rustc_hir::def_id::DefId>, Vec<rustc_hir::def_id::DefId>;
[] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>, [few] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels, rustc_middle::middle::privacy::AccessLevels;
[] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, [few] foreign_module: rustc_middle::middle::cstore::ForeignModule, rustc_middle::middle::cstore::ForeignModule;
[] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>, [few] foreign_modules: Vec<rustc_middle::middle::cstore::ForeignModule>, Vec<rustc_middle::middle::cstore::ForeignModule>;
[] attribute: rustc_ast::ast::Attribute, [] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>, rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>;
[] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>, [] object_safety_violations: rustc_middle::traits::ObjectSafetyViolation, rustc_middle::traits::ObjectSafetyViolation;
[] hir_id_set: rustc_hir::HirIdSet, [] codegen_unit: rustc_middle::mir::mono::CodegenUnit<$tcx>, rustc_middle::mir::mono::CodegenUnit<'_x>;
[] attribute: rustc_ast::ast::Attribute, rustc_ast::ast::Attribute;
[] name_set: rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>, rustc_data_structures::fx::FxHashSet<rustc_span::symbol::Symbol>;
[] hir_id_set: rustc_hir::HirIdSet, rustc_hir::HirIdSet;
// Interned types // Interned types
[] tys: rustc_middle::ty::TyS<$tcx>, [] tys: rustc_middle::ty::TyS<$tcx>, rustc_middle::ty::TyS<'_x>;
// HIR query types // HIR query types
[few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>, [few] indexed_hir: rustc_middle::hir::map::IndexedHir<$tcx>, rustc_middle::hir::map::IndexedHir<'_x>;
[few] hir_definitions: rustc_hir::definitions::Definitions, [few] hir_definitions: rustc_hir::definitions::Definitions, rustc_hir::definitions::Definitions;
[] hir_owner: rustc_middle::hir::Owner<$tcx>, [] hir_owner: rustc_middle::hir::Owner<$tcx>, rustc_middle::hir::Owner<'_x>;
[] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>, [] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$tcx>, rustc_middle::hir::OwnerNodes<'_x>;
// Note that this deliberately duplicates items in the `rustc_hir::arena`, // Note that this deliberately duplicates items in the `rustc_hir::arena`,
// since we need to allocate this type on both the `rustc_hir` arena // since we need to allocate this type on both the `rustc_hir` arena
// (during lowering) and the `librustc_middle` arena (for decoding MIR) // (during lowering) and the `librustc_middle` arena (for decoding MIR)
[decode] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, [decode] asm_template: rustc_ast::ast::InlineAsmTemplatePiece, rustc_ast::ast::InlineAsmTemplatePiece;
// This is used to decode the &'tcx [Span] for InlineAsm's line_spans. // This is used to decode the &'tcx [Span] for InlineAsm's line_spans.
[decode] span: rustc_span::Span, [decode] span: rustc_span::Span, rustc_span::Span;
], $tcx); ], $tcx);
) )
} }
......
...@@ -128,7 +128,7 @@ pub fn can_reconstruct_query_key<$tcx>(&self) -> bool { ...@@ -128,7 +128,7 @@ pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
// tuple args // tuple args
$({ $({
return <$tuple_arg_ty as DepNodeParams<TyCtxt<'_>>> return <$tuple_arg_ty as DepNodeParams<TyCtxt<'_>>>
::CAN_RECONSTRUCT_QUERY_KEY; ::can_reconstruct_query_key();
})* })*
true true
...@@ -304,7 +304,10 @@ pub mod label_strs { ...@@ -304,7 +304,10 @@ pub mod label_strs {
]); ]);
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for DefId { impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for DefId {
const CAN_RECONSTRUCT_QUERY_KEY: bool = true; #[inline]
fn can_reconstruct_query_key() -> bool {
true
}
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
tcx.def_path_hash(*self).0 tcx.def_path_hash(*self).0
...@@ -320,7 +323,10 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { ...@@ -320,7 +323,10 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
} }
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalDefId { impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalDefId {
const CAN_RECONSTRUCT_QUERY_KEY: bool = true; #[inline]
fn can_reconstruct_query_key() -> bool {
true
}
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx) self.to_def_id().to_fingerprint(tcx)
...@@ -336,7 +342,10 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { ...@@ -336,7 +342,10 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
} }
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum { impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum {
const CAN_RECONSTRUCT_QUERY_KEY: bool = true; #[inline]
fn can_reconstruct_query_key() -> bool {
true
}
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX }; let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
...@@ -353,7 +362,10 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { ...@@ -353,7 +362,10 @@ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
} }
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) { impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
const CAN_RECONSTRUCT_QUERY_KEY: bool = false; #[inline]
fn can_reconstruct_query_key() -> bool {
false
}
// We actually would not need to specialize the implementation of this // We actually would not need to specialize the implementation of this
// method but it's faster to combine the hashes than to instantiate a full // method but it's faster to combine the hashes than to instantiate a full
...@@ -375,7 +387,10 @@ fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { ...@@ -375,7 +387,10 @@ fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
} }
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
const CAN_RECONSTRUCT_QUERY_KEY: bool = false; #[inline]
fn can_reconstruct_query_key() -> bool {
false
}
// We actually would not need to specialize the implementation of this // We actually would not need to specialize the implementation of this
// method but it's faster to combine the hashes than to instantiate a full // method but it's faster to combine the hashes than to instantiate a full
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#![feature(option_expect_none)] #![feature(option_expect_none)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(range_is_empty)] #![feature(range_is_empty)]
#![feature(specialization)] // FIXME: min_specialization does not work #![feature(min_specialization)]
#![feature(track_caller)] #![feature(track_caller)]
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(vec_remove_item)] #![feature(vec_remove_item)]
......
...@@ -457,8 +457,39 @@ pub fn assert_crate_local(self) -> T { ...@@ -457,8 +457,39 @@ pub fn assert_crate_local(self) -> T {
} }
} }
impl<T: Encodable> rustc_serialize::UseSpecializedEncodable for ClearCrossCrate<T> {} const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
impl<T: Decodable> rustc_serialize::UseSpecializedDecodable for ClearCrossCrate<T> {} const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
impl<T: Encodable> rustc_serialize::UseSpecializedEncodable for ClearCrossCrate<T> {
#[inline]
fn default_encode<E: rustc_serialize::Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
match *self {
ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(e),
ClearCrossCrate::Set(ref val) => {
TAG_CLEAR_CROSS_CRATE_SET.encode(e)?;
val.encode(e)
}
}
}
}
impl<T: Decodable> rustc_serialize::UseSpecializedDecodable for ClearCrossCrate<T> {
#[inline]
fn default_decode<D>(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error>
where
D: rustc_serialize::Decoder,
{
let discr = u8::decode(d)?;
match discr {
TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(ClearCrossCrate::Clear),
TAG_CLEAR_CROSS_CRATE_SET => {
let val = T::decode(d)?;
Ok(ClearCrossCrate::Set(val))
}
_ => unreachable!(),
}
}
}
/// Grouped information about the source code origin of a MIR entity. /// Grouped information about the source code origin of a MIR entity.
/// Intended to be inspected by diagnostics and debuginfo. /// Intended to be inspected by diagnostics and debuginfo.
...@@ -1957,8 +1988,6 @@ fn is_indirect(&self) -> bool { ...@@ -1957,8 +1988,6 @@ fn is_indirect(&self) -> bool {
/// and the index is a local. /// and the index is a local.
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>; pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
impl<'tcx> Copy for PlaceElem<'tcx> {}
// At least on 64 bit systems, `PlaceElem` should not be larger than two pointers. // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
static_assert_size!(PlaceElem<'_>, 16); static_assert_size!(PlaceElem<'_>, 16);
......
...@@ -97,7 +97,7 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E, value: &T, cache: M) -> R ...@@ -97,7 +97,7 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E, value: &T, cache: M) -> R
pub fn encode_spanned_predicates<'tcx, E, C>( pub fn encode_spanned_predicates<'tcx, E, C>(
encoder: &mut E, encoder: &mut E,
predicates: &'tcx [(ty::Predicate<'tcx>, Span)], predicates: &[(ty::Predicate<'tcx>, Span)],
cache: C, cache: C,
) -> Result<(), E::Error> ) -> Result<(), E::Error>
where where
...@@ -139,7 +139,7 @@ fn positioned_at_shorthand(&self) -> bool { ...@@ -139,7 +139,7 @@ fn positioned_at_shorthand(&self) -> bool {
} }
#[inline] #[inline]
pub fn decode_arena_allocable<D, T: ArenaAllocatable + Decodable>( pub fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
decoder: &mut D, decoder: &mut D,
) -> Result<&'tcx T, D::Error> ) -> Result<&'tcx T, D::Error>
where where
...@@ -149,7 +149,7 @@ pub fn decode_arena_allocable<D, T: ArenaAllocatable + Decodable>( ...@@ -149,7 +149,7 @@ pub fn decode_arena_allocable<D, T: ArenaAllocatable + Decodable>(
} }
#[inline] #[inline]
pub fn decode_arena_allocable_slice<D, T: ArenaAllocatable + Decodable>( pub fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
decoder: &mut D, decoder: &mut D,
) -> Result<&'tcx [T], D::Error> ) -> Result<&'tcx [T], D::Error>
where where
...@@ -318,18 +318,38 @@ fn $name(&mut self) -> Result<$ty, Self::Error> { ...@@ -318,18 +318,38 @@ fn $name(&mut self) -> Result<$ty, Self::Error> {
macro_rules! impl_arena_allocatable_decoder { macro_rules! impl_arena_allocatable_decoder {
([]$args:tt) => {}; ([]$args:tt) => {};
([decode $(, $attrs:ident)*] ([decode $(, $attrs:ident)*]
[[$DecoderName:ident [$($typaram:tt),*]], [$name:ident: $ty:ty], $tcx:lifetime]) => { [[$DecoderName:ident [$($typaram:tt),*]], [$name:ident: $ty:ty, $gen_ty:ty], $tcx:lifetime]) => {
impl<$($typaram),*> SpecializedDecoder<&$tcx $ty> for $DecoderName<$($typaram),*> { // FIXME(#36588): These impls are horribly unsound as they allow
// the caller to pick any lifetime for `'tcx`, including `'static`.
#[allow(unused_lifetimes)]
impl<'_x, '_y, '_z, '_w, '_a, $($typaram),*> SpecializedDecoder<&'_a $gen_ty>
for $DecoderName<$($typaram),*>
where &'_a $gen_ty: UseSpecializedDecodable
{
#[inline] #[inline]
fn specialized_decode(&mut self) -> Result<&$tcx $ty, Self::Error> { fn specialized_decode(&mut self) -> Result<&'_a $gen_ty, Self::Error> {
decode_arena_allocable(self) unsafe {
std::mem::transmute::<
Result<&$tcx $ty, Self::Error>,
Result<&'_a $gen_ty, Self::Error>,
>(decode_arena_allocable(self))
}
} }
} }
impl<$($typaram),*> SpecializedDecoder<&$tcx [$ty]> for $DecoderName<$($typaram),*> { #[allow(unused_lifetimes)]
impl<'_x, '_y, '_z, '_w, '_a, $($typaram),*> SpecializedDecoder<&'_a [$gen_ty]>
for $DecoderName<$($typaram),*>
where &'_a [$gen_ty]: UseSpecializedDecodable
{
#[inline] #[inline]
fn specialized_decode(&mut self) -> Result<&$tcx [$ty], Self::Error> { fn specialized_decode(&mut self) -> Result<&'_a [$gen_ty], Self::Error> {
decode_arena_allocable_slice(self) unsafe {
std::mem::transmute::<
Result<&$tcx [$ty], Self::Error>,
Result<&'_a [$gen_ty], Self::Error>,
>(decode_arena_allocable_slice(self))
}
} }
} }
}; };
...@@ -340,9 +360,9 @@ fn specialized_decode(&mut self) -> Result<&$tcx [$ty], Self::Error> { ...@@ -340,9 +360,9 @@ fn specialized_decode(&mut self) -> Result<&$tcx [$ty], Self::Error> {
#[macro_export] #[macro_export]
macro_rules! impl_arena_allocatable_decoders { macro_rules! impl_arena_allocatable_decoders {
($args:tt, [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { ($args:tt, [$($a:tt $name:ident: $ty:ty, $gen_ty:ty;)*], $tcx:lifetime) => {
$( $(
impl_arena_allocatable_decoder!($a [$args, [$name: $ty], $tcx]); impl_arena_allocatable_decoder!($a [$args, [$name: $ty, $gen_ty], $tcx]);
)* )*
} }
} }
...@@ -352,14 +372,15 @@ fn specialized_decode(&mut self) -> Result<&$tcx [$ty], Self::Error> { ...@@ -352,14 +372,15 @@ fn specialized_decode(&mut self) -> Result<&$tcx [$ty], Self::Error> {
($DecoderName:ident <$($typaram:tt),*>) => { ($DecoderName:ident <$($typaram:tt),*>) => {
mod __ty_decoder_impl { mod __ty_decoder_impl {
use std::borrow::Cow; use std::borrow::Cow;
use std::mem::transmute;
use rustc_serialize::{Decoder, SpecializedDecoder}; use rustc_serialize::{Decoder, SpecializedDecoder, UseSpecializedDecodable};
use $crate::infer::canonical::CanonicalVarInfos; use $crate::infer::canonical::CanonicalVarInfos;
use $crate::ty; use $crate::ty;
use $crate::ty::codec::*; use $crate::ty::codec::*;
use $crate::ty::subst::SubstsRef; use $crate::ty::subst::InternalSubsts;
use rustc_hir::def_id::{CrateNum}; use rustc_hir::def_id::CrateNum;
use rustc_span::Span; use rustc_span::Span;
...@@ -398,8 +419,7 @@ fn error(&mut self, err: &str) -> Self::Error { ...@@ -398,8 +419,7 @@ fn error(&mut self, err: &str) -> Self::Error {
} }
// FIXME(#36588): These impls are horribly unsound as they allow // FIXME(#36588): These impls are horribly unsound as they allow
// the caller to pick any lifetime for `'tcx`, including `'static`, // the caller to pick any lifetime for `'tcx`, including `'static`.
// by using the unspecialized proxies to them.
rustc_hir::arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx); rustc_hir::arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx); arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
...@@ -411,90 +431,98 @@ fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> { ...@@ -411,90 +431,98 @@ fn specialized_decode(&mut self) -> Result<CrateNum, Self::Error> {
} }
} }
impl<$($typaram),*> SpecializedDecoder<ty::Ty<'tcx>> impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x ty::TyS<'_y>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*>
fn specialized_decode(&mut self) -> Result<ty::Ty<'tcx>, Self::Error> { where &'_x ty::TyS<'_y>: UseSpecializedDecodable
decode_ty(self) {
fn specialized_decode(&mut self) -> Result<&'_x ty::TyS<'_y>, Self::Error> {
unsafe { transmute::<Result<ty::Ty<'tcx>, Self::Error>, Result<&'_x ty::TyS<'_y>, Self::Error>>(decode_ty(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<&'tcx [(ty::Predicate<'tcx>, Span)]> impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x [(ty::Predicate<'_y>, Span)]>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*>
where &'_x [(ty::Predicate<'_y>, Span)]: UseSpecializedDecodable {
fn specialized_decode(&mut self) fn specialized_decode(&mut self)
-> Result<&'tcx [(ty::Predicate<'tcx>, Span)], Self::Error> { -> Result<&'_x [(ty::Predicate<'_y>, Span)], Self::Error>
decode_spanned_predicates(self) {
unsafe { transmute(decode_spanned_predicates(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<SubstsRef<'tcx>> impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x InternalSubsts<'_y>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*>
fn specialized_decode(&mut self) -> Result<SubstsRef<'tcx>, Self::Error> { where &'_x InternalSubsts<'_y>: UseSpecializedDecodable {
decode_substs(self) fn specialized_decode(&mut self) -> Result<&'_x InternalSubsts<'_y>, Self::Error> {
unsafe { transmute(decode_substs(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<$crate::mir::Place<'tcx>> impl<'_x, $($typaram),*> SpecializedDecoder<$crate::mir::Place<'_x>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*> {
fn specialized_decode( fn specialized_decode(
&mut self &mut self
) -> Result<$crate::mir::Place<'tcx>, Self::Error> { ) -> Result<$crate::mir::Place<'_x>, Self::Error> {
decode_place(self) unsafe { transmute(decode_place(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<ty::Region<'tcx>> impl<'_x, $($typaram),*> SpecializedDecoder<ty::Region<'_x>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self) -> Result<ty::Region<'tcx>, Self::Error> { fn specialized_decode(&mut self) -> Result<ty::Region<'_x>, Self::Error> {
decode_region(self) unsafe { transmute(decode_region(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<&'tcx ty::List<ty::Ty<'tcx>>> impl<'_x, '_y, '_z, $($typaram),*> SpecializedDecoder<&'_x ty::List<&'_y ty::TyS<'_z>>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*>
where &'_x ty::List<&'_y ty::TyS<'_z>>: UseSpecializedDecodable {
fn specialized_decode(&mut self) fn specialized_decode(&mut self)
-> Result<&'tcx ty::List<ty::Ty<'tcx>>, Self::Error> { -> Result<&'_x ty::List<&'_y ty::TyS<'_z>>, Self::Error> {
decode_ty_slice(self) unsafe { transmute(decode_ty_slice(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<&'tcx ty::AdtDef> impl<'_x, $($typaram),*> SpecializedDecoder<&'_x ty::AdtDef>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self) -> Result<&'tcx ty::AdtDef, Self::Error> { fn specialized_decode(&mut self) -> Result<&'_x ty::AdtDef, Self::Error> {
decode_adt_def(self) unsafe { transmute(decode_adt_def(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>> impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x ty::List<ty::ExistentialPredicate<'_y>>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*>
where &'_x ty::List<ty::ExistentialPredicate<'_y>>: UseSpecializedDecodable {
fn specialized_decode(&mut self) fn specialized_decode(&mut self)
-> Result<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>, Self::Error> { -> Result<&'_x ty::List<ty::ExistentialPredicate<'_y>>, Self::Error> {
decode_existential_predicate_slice(self) unsafe { transmute(decode_existential_predicate_slice(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<CanonicalVarInfos<'tcx>> impl<'_x, $($typaram),*> SpecializedDecoder<CanonicalVarInfos<'_x>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self) fn specialized_decode(&mut self)
-> Result<CanonicalVarInfos<'tcx>, Self::Error> { -> Result<CanonicalVarInfos<'_x>, Self::Error> {
decode_canonical_var_infos(self) unsafe { transmute(decode_canonical_var_infos(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>> impl<'_x, '_y, $($typaram),*> SpecializedDecoder<&'_x $crate::ty::Const<'_y>>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*>
fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { where &'_x $crate::ty::Const<'_y>: UseSpecializedDecodable {
decode_const(self) fn specialized_decode(&mut self) -> Result<&'_x ty::Const<'_y>, Self::Error> {
unsafe { transmute(decode_const(self)) }
} }
} }
impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::mir::interpret::Allocation> impl<'_x, $($typaram),*> SpecializedDecoder<&'_x $crate::mir::interpret::Allocation>
for $DecoderName<$($typaram),*> { for $DecoderName<$($typaram),*> {
fn specialized_decode( fn specialized_decode(
&mut self &mut self
) -> Result<&'tcx $crate::mir::interpret::Allocation, Self::Error> { ) -> Result<&'_x $crate::mir::interpret::Allocation, Self::Error> {
decode_allocation(self) unsafe { transmute(decode_allocation(self)) }
} }
} }
} }
} };
} }
use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
use crate::mir::interpret;
use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use crate::mir::{self, interpret};
use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder}; use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
use crate::ty::context::TyCtxt; use crate::ty::context::TyCtxt;
use crate::ty::{self, Ty}; use crate::ty::{self, Ty};
...@@ -26,9 +26,6 @@ ...@@ -26,9 +26,6 @@
const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
const TAG_NO_EXPN_DATA: u8 = 0; const TAG_NO_EXPN_DATA: u8 = 0;
const TAG_EXPN_DATA_SHORTHAND: u8 = 1; const TAG_EXPN_DATA_SHORTHAND: u8 = 1;
const TAG_EXPN_DATA_INLINE: u8 = 2; const TAG_EXPN_DATA_INLINE: u8 = 2;
...@@ -667,24 +664,6 @@ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> { ...@@ -667,24 +664,6 @@ fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
} }
} }
impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
for CacheDecoder<'a, 'tcx>
{
#[inline]
fn specialized_decode(&mut self) -> Result<mir::ClearCrossCrate<T>, Self::Error> {
let discr = u8::decode(self)?;
match discr {
TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(mir::ClearCrossCrate::Clear),
TAG_CLEAR_CROSS_CRATE_SET => {
let val = T::decode(self)?;
Ok(mir::ClearCrossCrate::Set(val))
}
_ => unreachable!(),
}
}
}
//- ENCODING ------------------------------------------------------------------- //- ENCODING -------------------------------------------------------------------
/// An encoder that can write the incr. comp. cache. /// An encoder that can write the incr. comp. cache.
...@@ -828,17 +807,20 @@ fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> { ...@@ -828,17 +807,20 @@ fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
} }
} }
impl<'a, 'tcx, E> SpecializedEncoder<Ty<'tcx>> for CacheEncoder<'a, 'tcx, E> impl<'a, 'b, 'c, 'tcx, E> SpecializedEncoder<&'b ty::TyS<'c>> for CacheEncoder<'a, 'tcx, E>
where where
E: 'a + TyEncoder, E: 'a + TyEncoder,
&'b ty::TyS<'c>: UseSpecializedEncodable,
{ {
#[inline] #[inline]
fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> { fn specialized_encode(&mut self, ty: &&'b ty::TyS<'c>) -> Result<(), Self::Error> {
debug_assert!(self.tcx.lift(ty).is_some());
let ty = unsafe { std::mem::transmute::<&&'b ty::TyS<'c>, &&'tcx ty::TyS<'tcx>>(ty) };
ty_codec::encode_with_shorthand(self, ty, |encoder| &mut encoder.type_shorthands) ty_codec::encode_with_shorthand(self, ty, |encoder| &mut encoder.type_shorthands)
} }
} }
impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> impl<'a, 'b, 'c, 'tcx, E> SpecializedEncoder<&'b [(ty::Predicate<'c>, Span)]>
for CacheEncoder<'a, 'tcx, E> for CacheEncoder<'a, 'tcx, E>
where where
E: 'a + TyEncoder, E: 'a + TyEncoder,
...@@ -846,8 +828,15 @@ impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> ...@@ -846,8 +828,15 @@ impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
#[inline] #[inline]
fn specialized_encode( fn specialized_encode(
&mut self, &mut self,
predicates: &&'tcx [(ty::Predicate<'tcx>, Span)], predicates: &&'b [(ty::Predicate<'c>, Span)],
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error> {
debug_assert!(self.tcx.lift(*predicates).is_some());
let predicates = unsafe {
std::mem::transmute::<
&&'b [(ty::Predicate<'c>, Span)],
&&'tcx [(ty::Predicate<'tcx>, Span)],
>(predicates)
};
ty_codec::encode_spanned_predicates(self, predicates, |encoder| { ty_codec::encode_spanned_predicates(self, predicates, |encoder| {
&mut encoder.predicate_shorthands &mut encoder.predicate_shorthands
}) })
...@@ -890,23 +879,6 @@ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { ...@@ -890,23 +879,6 @@ fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
} }
} }
impl<'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>> for CacheEncoder<'a, 'tcx, E>
where
E: 'a + TyEncoder,
T: Encodable,
{
#[inline]
fn specialized_encode(&mut self, val: &mir::ClearCrossCrate<T>) -> Result<(), Self::Error> {
match *val {
mir::ClearCrossCrate::Clear => TAG_CLEAR_CROSS_CRATE_CLEAR.encode(self),
mir::ClearCrossCrate::Set(ref val) => {
TAG_CLEAR_CROSS_CRATE_SET.encode(self)?;
val.encode(self)
}
}
}
}
macro_rules! encoder_methods { macro_rules! encoder_methods {
($($name:ident($ty:ty);)*) => { ($($name:ident($ty:ty);)*) => {
#[inline] #[inline]
...@@ -995,7 +967,7 @@ fn encode_query_results<'a, 'tcx, Q, E>( ...@@ -995,7 +967,7 @@ fn encode_query_results<'a, 'tcx, Q, E>(
query_result_index: &mut EncodedQueryResultIndex, query_result_index: &mut EncodedQueryResultIndex,
) -> Result<(), E::Error> ) -> Result<(), E::Error>
where where
Q: super::QueryDescription<TyCtxt<'tcx>>, Q: super::QueryDescription<TyCtxt<'tcx>> + super::QueryAccessors<TyCtxt<'tcx>>,
Q::Value: Encodable, Q::Value: Encodable,
E: 'a + TyEncoder, E: 'a + TyEncoder,
{ {
......
...@@ -112,30 +112,53 @@ impl<T: Debug> IntoSelfProfilingString for T { ...@@ -112,30 +112,53 @@ impl<T: Debug> IntoSelfProfilingString for T {
} }
} }
impl IntoSelfProfilingString for DefId { impl<T: SpecIntoSelfProfilingString> IntoSelfProfilingString for T {
fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId {
self.spec_to_self_profile_string(builder)
}
}
#[rustc_specialization_trait]
pub trait SpecIntoSelfProfilingString: Debug {
fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId;
}
impl SpecIntoSelfProfilingString for DefId {
fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId {
builder.def_id_to_string_id(*self) builder.def_id_to_string_id(*self)
} }
} }
impl IntoSelfProfilingString for CrateNum { impl SpecIntoSelfProfilingString for CrateNum {
fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId {
builder.def_id_to_string_id(DefId { krate: *self, index: CRATE_DEF_INDEX }) builder.def_id_to_string_id(DefId { krate: *self, index: CRATE_DEF_INDEX })
} }
} }
impl IntoSelfProfilingString for DefIndex { impl SpecIntoSelfProfilingString for DefIndex {
fn to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_, '_>) -> StringId { fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId {
builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: *self }) builder.def_id_to_string_id(DefId { krate: LOCAL_CRATE, index: *self })
} }
} }
impl<T0, T1> IntoSelfProfilingString for (T0, T1) impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1)
where where
T0: IntoSelfProfilingString + Debug, T0: SpecIntoSelfProfilingString,
T1: IntoSelfProfilingString + Debug, T1: SpecIntoSelfProfilingString,
{ {
default fn to_self_profile_string( fn spec_to_self_profile_string(
&self, &self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>, builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId { ) -> StringId {
......
use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt}; use crate::ty::{self, AdtSizedConstraint, Ty, TyCtxt, TyS};
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
...@@ -13,9 +13,11 @@ impl<'tcx, T> Value<'tcx> for T { ...@@ -13,9 +13,11 @@ impl<'tcx, T> Value<'tcx> for T {
} }
} }
impl<'tcx> Value<'tcx> for Ty<'tcx> { impl<'tcx> Value<'tcx> for &'_ TyS<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> { fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
tcx.types.err // SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow.
unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.types.err) }
} }
} }
...@@ -25,8 +27,14 @@ fn from_cycle_error(_: TyCtxt<'tcx>) -> Self { ...@@ -25,8 +27,14 @@ fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
} }
} }
impl<'tcx> Value<'tcx> for AdtSizedConstraint<'tcx> { impl<'tcx> Value<'tcx> for AdtSizedConstraint<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self { fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err])) // SAFETY: This is never called when `Self` is not `AdtSizedConstraint<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow.
unsafe {
std::mem::transmute::<AdtSizedConstraint<'tcx>, AdtSizedConstraint<'_>>(
AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err])),
)
}
} }
} }
...@@ -2409,8 +2409,6 @@ pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 { ...@@ -2409,8 +2409,6 @@ pub fn eval_usize(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> u64 {
} }
} }
impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}
/// Represents a constant in Rust. /// Represents a constant in Rust.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
#[derive(HashStable)] #[derive(HashStable)]
......
...@@ -91,7 +91,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ...@@ -91,7 +91,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
} }
pub trait DepNodeParams<Ctxt: DepContext>: fmt::Debug + Sized { pub trait DepNodeParams<Ctxt: DepContext>: fmt::Debug + Sized {
const CAN_RECONSTRUCT_QUERY_KEY: bool; fn can_reconstruct_query_key() -> bool;
/// This method turns the parameters of a DepNodeConstructor into an opaque /// This method turns the parameters of a DepNodeConstructor into an opaque
/// Fingerprint to be used in DepNode. /// Fingerprint to be used in DepNode.
...@@ -108,7 +108,7 @@ fn to_debug_str(&self, _: Ctxt) -> String { ...@@ -108,7 +108,7 @@ fn to_debug_str(&self, _: Ctxt) -> String {
/// This method tries to recover the query key from the given `DepNode`, /// This method tries to recover the query key from the given `DepNode`,
/// something which is needed when forcing `DepNode`s during red-green /// something which is needed when forcing `DepNode`s during red-green
/// evaluation. The query system will only call this method if /// evaluation. The query system will only call this method if
/// `CAN_RECONSTRUCT_QUERY_KEY` is `true`. /// `can_reconstruct_query_key()` is `true`.
/// It is always valid to return `None` here, in which case incremental /// It is always valid to return `None` here, in which case incremental
/// compilation will treat the query as having changed instead of forcing it. /// compilation will treat the query as having changed instead of forcing it.
fn recover(tcx: Ctxt, dep_node: &DepNode<Ctxt::DepKind>) -> Option<Self>; fn recover(tcx: Ctxt, dep_node: &DepNode<Ctxt::DepKind>) -> Option<Self>;
...@@ -118,7 +118,10 @@ impl<Ctxt: DepContext, T> DepNodeParams<Ctxt> for T ...@@ -118,7 +118,10 @@ impl<Ctxt: DepContext, T> DepNodeParams<Ctxt> for T
where where
T: HashStable<Ctxt::StableHashingContext> + fmt::Debug, T: HashStable<Ctxt::StableHashingContext> + fmt::Debug,
{ {
default const CAN_RECONSTRUCT_QUERY_KEY: bool = false; #[inline]
default fn can_reconstruct_query_key() -> bool {
false
}
default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint { default fn to_fingerprint(&self, tcx: Ctxt) -> Fingerprint {
let mut hcx = tcx.create_stable_hashing_context(); let mut hcx = tcx.create_stable_hashing_context();
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#![feature(const_panic)] #![feature(const_panic)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(hash_raw_entry)] #![feature(hash_raw_entry)]
#![feature(specialization)] // FIXME: min_specialization rejects `default const` #![feature(min_specialization)]
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
#![feature(vec_remove_item)] #![feature(vec_remove_item)]
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
test(attr(allow(unused_variables), deny(warnings))) test(attr(allow(unused_variables), deny(warnings)))
)] )]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(specialization)] // FIXME: min_specialization does not work #![feature(min_specialization)]
#![feature(never_type)] #![feature(never_type)]
#![feature(nll)] #![feature(nll)]
#![feature(associated_type_bounds)] #![feature(associated_type_bounds)]
......
...@@ -635,24 +635,6 @@ fn decode<D: Decoder>(d: &mut D) -> Result<PhantomData<T>, D::Error> { ...@@ -635,24 +635,6 @@ fn decode<D: Decoder>(d: &mut D) -> Result<PhantomData<T>, D::Error> {
} }
} }
impl<'a, T: ?Sized + Encodable> Encodable for &'a T {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(**self).encode(s)
}
}
impl<T: ?Sized + Encodable> Encodable for Box<T> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(**self).encode(s)
}
}
impl<T: Decodable> Decodable for Box<T> {
fn decode<D: Decoder>(d: &mut D) -> Result<Box<T>, D::Error> {
Ok(box Decodable::decode(d)?)
}
}
impl<T: Decodable> Decodable for Box<[T]> { impl<T: Decodable> Decodable for Box<[T]> {
fn decode<D: Decoder>(d: &mut D) -> Result<Box<[T]>, D::Error> { fn decode<D: Decoder>(d: &mut D) -> Result<Box<[T]>, D::Error> {
let v: Vec<T> = Decodable::decode(d)?; let v: Vec<T> = Decodable::decode(d)?;
...@@ -1008,8 +990,20 @@ impl<T: UseSpecializedDecodable> Decodable for T { ...@@ -1008,8 +990,20 @@ impl<T: UseSpecializedDecodable> Decodable for T {
// for this exact reason. // for this exact reason.
// May be fixable in a simpler fashion via the // May be fixable in a simpler fashion via the
// more complex lattice model for specialization. // more complex lattice model for specialization.
impl<'a, T: ?Sized + Encodable> UseSpecializedEncodable for &'a T {} impl<'a, T: ?Sized + Encodable> UseSpecializedEncodable for &'a T {
impl<T: ?Sized + Encodable> UseSpecializedEncodable for Box<T> {} fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
impl<T: Decodable> UseSpecializedDecodable for Box<T> {} (**self).encode(s)
}
}
impl<T: ?Sized + Encodable> UseSpecializedEncodable for Box<T> {
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
(**self).encode(s)
}
}
impl<T: Decodable> UseSpecializedDecodable for Box<T> {
fn default_decode<D: Decoder>(d: &mut D) -> Result<Box<T>, D::Error> {
Ok(box Decodable::decode(d)?)
}
}
impl<'a, T: Decodable> UseSpecializedDecodable for &'a T {} impl<'a, T: Decodable> UseSpecializedDecodable for &'a T {}
impl<'a, T: Decodable> UseSpecializedDecodable for &'a [T] {} impl<'a, T: Decodable> UseSpecializedDecodable for &'a [T] {}
...@@ -90,7 +90,7 @@ fn enter_canonical_trait_query<K, R>( ...@@ -90,7 +90,7 @@ fn enter_canonical_trait_query<K, R>(
where where
K: TypeFoldable<'tcx>, K: TypeFoldable<'tcx>,
R: Debug + TypeFoldable<'tcx>, R: Debug + TypeFoldable<'tcx>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable; Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>;
} }
impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
...@@ -118,7 +118,7 @@ fn enter_canonical_trait_query<K, R>( ...@@ -118,7 +118,7 @@ fn enter_canonical_trait_query<K, R>(
where where
K: TypeFoldable<'tcx>, K: TypeFoldable<'tcx>,
R: Debug + TypeFoldable<'tcx>, R: Debug + TypeFoldable<'tcx>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
{ {
self.enter_with_canonical( self.enter_with_canonical(
DUMMY_SP, DUMMY_SP,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册