提交 af46d69b 编写于 作者: E est31

Remove Reflect

* Remove the Reflect trait
* Remove the "reflect" lang feature
上级 d2d8ae65
......@@ -82,7 +82,6 @@
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
#![feature(reflect)]
#![feature(unwind_attributes)]
#![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)]
......
......@@ -553,59 +553,3 @@ unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
}
/// Types that can be reflected over.
///
/// By "reflection" we mean use of the [`Any`][any] trait, or related
/// machinery such as [`TypeId`][typeid].
///
/// `Reflect` is implemented for all types. Its purpose is to ensure
/// that when you write a generic function that will employ reflection,
/// that must be reflected (no pun intended) in the generic bounds of
/// that function.
///
/// ```
/// #![feature(reflect_marker)]
/// use std::marker::Reflect;
/// use std::any::Any;
///
/// # #[allow(dead_code)]
/// fn foo<T: Reflect + 'static>(x: &T) {
/// let any: &Any = x;
/// if any.is::<u32>() { println!("u32"); }
/// }
/// ```
///
/// Without the bound `T: Reflect`, `foo` would not typecheck. (As
/// a matter of style, it would be preferable to write `T: Any`,
/// because `T: Any` implies `T: Reflect` and `T: 'static`, but we
/// use `Reflect` here for illustrative purposes.)
///
/// The `Reflect` bound serves to alert `foo`'s caller to the
/// fact that `foo` may behave differently depending on whether
/// `T` is `u32` or not. The ability for a caller to reason about what
/// a function may do based solely on what generic bounds are declared
/// is often called the "[parametricity property][param]". Despite the
/// use of `Reflect`, Rust lacks true parametricity because a generic
/// function can, at the very least, call [`mem::size_of`][size_of]
/// without employing any trait bounds whatsoever.
///
/// [any]: ../any/trait.Any.html
/// [typeid]: ../any/struct.TypeId.html
/// [param]: http://en.wikipedia.org/wiki/Parametricity
/// [size_of]: ../mem/fn.size_of.html
#[rustc_reflect_like]
#[unstable(feature = "reflect_marker",
reason = "requires RFC and more experience",
issue = "27749")]
#[rustc_deprecated(since = "1.14.0", reason = "Specialization makes parametricity impossible")]
#[rustc_on_unimplemented = "`{Self}` does not implement `Any`; \
ensure all type parameters are bounded by `Any`"]
pub trait Reflect {}
#[unstable(feature = "reflect_marker",
reason = "requires RFC and more experience",
issue = "27749")]
#[rustc_deprecated(since = "1.14.0", reason = "Specialization makes parametricity impossible")]
#[allow(deprecated)]
impl Reflect for .. { }
......@@ -204,7 +204,6 @@ enum SelectionCandidate<'tcx> {
ParamCandidate(ty::PolyTraitRef<'tcx>),
ImplCandidate(DefId),
DefaultImplCandidate(DefId),
DefaultImplObjectCandidate(DefId),
/// This is a trait matching with a projected type as `Self`, and
/// we found an applicable bound in the trait definition.
......@@ -237,9 +236,6 @@ fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lif
}
ImplCandidate(def_id) => ImplCandidate(def_id),
DefaultImplCandidate(def_id) => DefaultImplCandidate(def_id),
DefaultImplObjectCandidate(def_id) => {
DefaultImplObjectCandidate(def_id)
}
ProjectionCandidate => ProjectionCandidate,
FnPointerCandidate => FnPointerCandidate,
ObjectCandidate => ObjectCandidate,
......@@ -1431,17 +1427,9 @@ fn assemble_candidates_from_default_impls(&mut self,
match self_ty.sty {
ty::TyDynamic(..) => {
// For object types, we don't know what the closed
// over types are. For most traits, this means we
// conservatively say nothing; a candidate may be
// added by `assemble_candidates_from_object_ty`.
// However, for the kind of magic reflect trait,
// we consider it to be implemented even for
// object types, because it just lets you reflect
// onto the object type, not into the object's
// interior.
if self.tcx().has_attr(def_id, "rustc_reflect_like") {
candidates.vec.push(DefaultImplObjectCandidate(def_id));
}
// over types are. This means we conservatively
// say nothing; a candidate may be added by
// `assemble_candidates_from_object_ty`.
}
ty::TyParam(..) |
ty::TyProjection(..) |
......@@ -1671,7 +1659,6 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
FnPointerCandidate |
BuiltinObjectCandidate |
BuiltinUnsizeCandidate |
DefaultImplObjectCandidate(..) |
BuiltinCandidate { .. } => {
// We have a where-clause so don't go around looking
// for impls.
......@@ -1998,11 +1985,6 @@ fn confirm_candidate(&mut self,
Ok(VtableDefaultImpl(data))
}
DefaultImplObjectCandidate(trait_def_id) => {
let data = self.confirm_default_impl_object_candidate(obligation, trait_def_id);
Ok(VtableDefaultImpl(data))
}
ImplCandidate(impl_def_id) => {
Ok(VtableImpl(self.confirm_impl_candidate(obligation, impl_def_id)))
}
......@@ -2138,42 +2120,6 @@ fn confirm_default_impl_candidate(&mut self,
self.vtable_default_impl(obligation, trait_def_id, ty::Binder(types))
}
fn confirm_default_impl_object_candidate(&mut self,
obligation: &TraitObligation<'tcx>,
trait_def_id: DefId)
-> VtableDefaultImplData<PredicateObligation<'tcx>>
{
debug!("confirm_default_impl_object_candidate({:?}, {:?})",
obligation,
trait_def_id);
assert!(self.tcx().has_attr(trait_def_id, "rustc_reflect_like"));
// OK to skip binder, it is reintroduced below
let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
match self_ty.sty {
ty::TyDynamic(ref data, ..) => {
// OK to skip the binder, it is reintroduced below
let principal = data.principal().unwrap();
let input_types = principal.input_types();
let assoc_types = data.projection_bounds()
.map(|pb| pb.skip_binder().ty);
let all_types: Vec<_> = input_types.chain(assoc_types)
.collect();
// reintroduce the two binding levels we skipped, then flatten into one
let all_types = ty::Binder(ty::Binder(all_types));
let all_types = self.tcx().flatten_late_bound_regions(&all_types);
self.vtable_default_impl(obligation, trait_def_id, all_types)
}
_ => {
bug!("asked to confirm default object implementation for non-object type: {:?}",
self_ty);
}
}
}
/// See `confirm_default_impl_candidate`
fn vtable_default_impl(&mut self,
obligation: &TraitObligation<'tcx>,
......
......@@ -124,7 +124,6 @@ pub fn new() -> Features {
(active, advanced_slice_patterns, "1.0.0", Some(23121)),
(active, box_syntax, "1.0.0", Some(27779)),
(active, placement_in_syntax, "1.0.0", Some(27779)),
(active, reflect, "1.0.0", Some(27749)),
(active, unboxed_closures, "1.0.0", Some(29625)),
(active, allocator, "1.0.0", Some(27389)),
......@@ -334,6 +333,7 @@ pub fn new() -> Features {
(removed, managed_boxes, "1.0.0", None),
// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
(removed, negate_unsigned, "1.0.0", Some(29645)),
(removed, reflect, "1.0.0", Some(27749)),
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
(removed, opt_out_copy, "1.0.0", None),
(removed, quad_precision_float, "1.0.0", None),
......@@ -731,10 +731,6 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
"unboxed_closures",
"unboxed_closures are still evolving",
cfg_fn!(unboxed_closures))),
("rustc_reflect_like", Whitelisted, Gated(Stability::Unstable,
"reflect",
"defining reflective traits is still evolving",
cfg_fn!(reflect))),
("windows_subsystem", Whitelisted, Gated(Stability::Unstable,
"windows_subsystem",
......
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(reflect_marker)]
// Test that types that appear in assoc bindings in an object
// type are subject to the reflect check.
use std::marker::Reflect;
use std::io::Write;
trait Get {
type Output;
fn get(self) -> Self::Output;
}
struct Struct<T>(T);
fn is_reflect<T:Reflect>() { }
fn a<T>() {
is_reflect::<Box<Get<Output=T>>>(); //~ ERROR E0277
}
fn ok_a<T: Reflect>() {
is_reflect::<Box<Get<Output=T>>>(); // OK
}
fn main() {
}
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(reflect_marker)]
// Test that types that appear in input types in an object type are
// subject to the reflect check.
use std::marker::Reflect;
use std::io::Write;
trait Get<T> {
fn get(self) -> T;
}
struct Struct<T>(T);
fn is_reflect<T:Reflect>() { }
fn a<T>() {
is_reflect::<T>(); //~ ERROR E0277
}
fn ok_a<T: Reflect>() {
is_reflect::<T>(); // OK
}
fn b<T>() {
is_reflect::<Box<Get<T>>>(); //~ ERROR E0277
}
fn ok_b<T: Reflect>() {
is_reflect::<Box<Get<T>>>(); // OK
}
fn c<T>() {
is_reflect::<Box<Get<Struct<T>>>>(); //~ ERROR E0277
}
fn main() {
is_reflect::<Box<Get<Struct<()>>>>(); // OK
}
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(reflect_marker)]
// Test that there is no way to get a generic type `T` to be
// considered as `Reflect` (or accessible via something that is
// considered `Reflect`) without a reflect bound, but that any
// concrete type works fine. Note that object types are tested
// separately.
use std::marker::Reflect;
use std::io::Write;
struct Struct<T>(T);
fn is_reflect<T:Reflect>() { }
fn c<T>() {
is_reflect::<Struct<T>>(); //~ ERROR E0277
}
fn ok_c<T: Reflect>() {
is_reflect::<Struct<T>>(); // OK
}
fn d<T>() {
is_reflect::<(i32, T)>(); //~ ERROR E0277
}
fn main() {
is_reflect::<&i32>(); // OK
is_reflect::<Box<Write>>(); // OK
}
......@@ -167,7 +167,7 @@ pub fn check(path: &Path, bad: &mut bool) {
// FIXME get this whitelist empty.
let whitelist = vec![
"abi_ptx", "simd", "macro_reexport",
"static_recursion", "reflect", "quote",
"static_recursion", "quote",
"cfg_target_has_atomic", "staged_api", "const_indexing",
"unboxed_closures", "stmt_expr_attributes",
"cfg_target_thread_local", "unwind_attributes",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册