Fix orphan checking (cc #19470). (This is not a complete fix of #19470 because of the backwards compatibility feature gate.)
This is a [breaking-change]. The new rules require that, for an impl of a trait defined in some other crate, two conditions must hold: 1. Some type must be local. 2. Every type parameter must appear "under" some local type. Here are some examples that are legal: ```rust struct MyStruct<T> { ... } // Here `T` appears "under' `MyStruct`. impl<T> Clone for MyStruct<T> { } // Here `T` appears "under' `MyStruct` as well. Note that it also appears // elsewhere. impl<T> Iterator<T> for MyStruct<T> { } ``` Here is an illegal example: ```rust // Here `U` does not appear "under" `MyStruct` or any other local type. // We call `U` "uncovered". impl<T,U> Iterator<U> for MyStruct<T> { } ``` There are a couple of ways to rewrite this last example so that it is legal: 1. In some cases, the uncovered type parameter (here, `U`) should be converted into an associated type. This is however a non-local change that requires access to the original trait. Also, associated types are not fully baked. 2. Add `U` as a type parameter of `MyStruct`: ```rust struct MyStruct<T,U> { ... } impl<T,U> Iterator<U> for MyStruct<T,U> { } ``` 3. Create a newtype wrapper for `U` ```rust impl<T,U> Iterator<Wrapper<U>> for MyStruct<T,U> { } ``` Because associated types are not fully baked, which in the case of the `Hash` trait makes adhering to this rule impossible, you can temporarily disable this rule in your crate by using `#![feature(old_orphan_check)]`. Note that the `old_orphan_check` feature will be removed before 1.0 is released.
This commit is contained in:
parent
77723d24a8
commit
c61a0092bc
@ -64,7 +64,8 @@
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![no_std]
|
||||
#![feature(lang_items, phase, unsafe_destructor, default_type_params)]
|
||||
#![allow(unknown_features)]
|
||||
#![feature(lang_items, phase, unsafe_destructor, default_type_params, old_orphan_check)]
|
||||
|
||||
#[phase(plugin, link)]
|
||||
extern crate core;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#![feature(macro_rules, default_type_params, phase, globs)]
|
||||
#![feature(unsafe_destructor, slicing_syntax)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
#![no_std]
|
||||
|
||||
#[phase(plugin, link)] extern crate core;
|
||||
|
@ -96,9 +96,9 @@ fn cmp(&self, other: &MaybeOwnedVector<T>) -> Ordering {
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl<'a, T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
|
||||
fn equiv(&self, other: &V) -> bool {
|
||||
self.as_slice() == other.as_slice()
|
||||
impl<'a, T: PartialEq> Equiv<[T]> for MaybeOwnedVector<'a, T> {
|
||||
fn equiv(&self, other: &[T]) -> bool {
|
||||
self.as_slice() == other
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,12 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(default_type_params, globs, macro_rules, phase, quote)]
|
||||
#![feature(slicing_syntax, unsafe_destructor)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate flate;
|
||||
|
@ -14,10 +14,10 @@
|
||||
use super::{Obligation, ObligationCause};
|
||||
use super::util;
|
||||
|
||||
use middle::subst;
|
||||
use middle::subst::Subst;
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::infer::InferCtxt;
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
@ -52,9 +52,21 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
|
||||
selcx.evaluate_impl(impl2_def_id, &obligation)
|
||||
}
|
||||
|
||||
pub fn impl_is_local(tcx: &ty::ctxt,
|
||||
impl_def_id: ast::DefId)
|
||||
-> bool
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum OrphanCheckErr {
|
||||
NoLocalInputType,
|
||||
UncoveredTypeParameter(ty::ParamTy),
|
||||
}
|
||||
|
||||
/// Checks the coherence orphan rules. `impl_def_id` should be the
|
||||
/// def-id of a trait impl. To pass, either the trait must be local, or else
|
||||
/// two conditions must be satisfied:
|
||||
///
|
||||
/// 1. At least one of the input types must involve a local type.
|
||||
/// 2. All type parameters must be covered by a local type.
|
||||
pub fn orphan_check(tcx: &ty::ctxt,
|
||||
impl_def_id: ast::DefId)
|
||||
-> Result<(), OrphanCheckErr>
|
||||
{
|
||||
debug!("impl_is_local({})", impl_def_id.repr(tcx));
|
||||
|
||||
@ -63,20 +75,40 @@ pub fn impl_is_local(tcx: &ty::ctxt,
|
||||
let trait_ref = ty::impl_trait_ref(tcx, impl_def_id).unwrap();
|
||||
debug!("trait_ref={}", trait_ref.repr(tcx));
|
||||
|
||||
// If the trait is local to the crate, ok.
|
||||
// If the *trait* is local to the crate, ok.
|
||||
if trait_ref.def_id.krate == ast::LOCAL_CRATE {
|
||||
debug!("trait {} is local to current crate",
|
||||
trait_ref.def_id.repr(tcx));
|
||||
return true;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Otherwise, at least one of the input types must be local to the
|
||||
// crate.
|
||||
trait_ref.input_types().iter().any(|&t| ty_is_local(tcx, t))
|
||||
// Check condition 1: at least one type must be local.
|
||||
if !trait_ref.input_types().iter().any(|&t| ty_reaches_local(tcx, t)) {
|
||||
return Err(OrphanCheckErr::NoLocalInputType);
|
||||
}
|
||||
|
||||
// Check condition 2: type parameters must be "covered" by a local type.
|
||||
let covered_params: HashSet<_> =
|
||||
trait_ref.input_types().iter()
|
||||
.flat_map(|&t| type_parameters_covered_by_ty(tcx, t).into_iter())
|
||||
.collect();
|
||||
let all_params: HashSet<_> =
|
||||
trait_ref.input_types().iter()
|
||||
.flat_map(|&t| type_parameters_reachable_from_ty(t).into_iter())
|
||||
.collect();
|
||||
for ¶m in all_params.difference(&covered_params) {
|
||||
return Err(OrphanCheckErr::UncoveredTypeParameter(param));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
debug!("ty_is_local({})", ty.repr(tcx));
|
||||
fn ty_reaches_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty.walk().any(|t| ty_is_local_constructor(tcx, t))
|
||||
}
|
||||
|
||||
fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
debug!("ty_is_local_constructor({})", ty.repr(tcx));
|
||||
|
||||
match ty.sty {
|
||||
ty::ty_bool |
|
||||
@ -84,78 +116,33 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
ty::ty_int(..) |
|
||||
ty::ty_uint(..) |
|
||||
ty::ty_float(..) |
|
||||
ty::ty_str(..) => {
|
||||
false
|
||||
}
|
||||
|
||||
ty::ty_unboxed_closure(..) => {
|
||||
// This routine is invoked on types specified by users as
|
||||
// part of an impl and hence an unboxed closure type
|
||||
// cannot appear.
|
||||
tcx.sess.bug("ty_is_local applied to unboxed closure type")
|
||||
}
|
||||
|
||||
ty::ty_str(..) |
|
||||
ty::ty_bare_fn(..) |
|
||||
ty::ty_closure(..) => {
|
||||
ty::ty_closure(..) |
|
||||
ty::ty_vec(..) |
|
||||
ty::ty_ptr(..) |
|
||||
ty::ty_rptr(..) |
|
||||
ty::ty_tup(..) |
|
||||
ty::ty_param(..) |
|
||||
ty::ty_projection(..) => {
|
||||
false
|
||||
}
|
||||
|
||||
ty::ty_uniq(t) => {
|
||||
ty::ty_enum(def_id, _) |
|
||||
ty::ty_struct(def_id, _) => {
|
||||
def_id.krate == ast::LOCAL_CRATE
|
||||
}
|
||||
|
||||
ty::ty_uniq(_) => { // treat ~T like Box<T>
|
||||
let krate = tcx.lang_items.owned_box().map(|d| d.krate);
|
||||
krate == Some(ast::LOCAL_CRATE) || ty_is_local(tcx, t)
|
||||
}
|
||||
|
||||
ty::ty_vec(t, _) |
|
||||
ty::ty_ptr(ty::mt { ty: t, .. }) |
|
||||
ty::ty_rptr(_, ty::mt { ty: t, .. }) => {
|
||||
ty_is_local(tcx, t)
|
||||
}
|
||||
|
||||
ty::ty_tup(ref ts) => {
|
||||
ts.iter().any(|&t| ty_is_local(tcx, t))
|
||||
}
|
||||
|
||||
ty::ty_enum(def_id, ref substs) |
|
||||
ty::ty_struct(def_id, ref substs) => {
|
||||
def_id.krate == ast::LOCAL_CRATE || {
|
||||
let variances = ty::item_variances(tcx, def_id);
|
||||
subst::ParamSpace::all().iter().any(|&space| {
|
||||
substs.types.get_slice(space).iter().enumerate().any(
|
||||
|(i, &t)| {
|
||||
match *variances.types.get(space, i) {
|
||||
ty::Bivariant => {
|
||||
// If Foo<T> is bivariant with respect to
|
||||
// T, then it doesn't matter whether T is
|
||||
// local or not, because `Foo<U>` for any
|
||||
// U will be a subtype of T.
|
||||
false
|
||||
}
|
||||
ty::Contravariant |
|
||||
ty::Covariant |
|
||||
ty::Invariant => {
|
||||
ty_is_local(tcx, t)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
krate == Some(ast::LOCAL_CRATE)
|
||||
}
|
||||
|
||||
ty::ty_trait(ref tt) => {
|
||||
tt.principal_def_id().krate == ast::LOCAL_CRATE
|
||||
}
|
||||
|
||||
// Type parameters may be bound to types that are not local to
|
||||
// the crate.
|
||||
ty::ty_param(..) => {
|
||||
false
|
||||
}
|
||||
|
||||
// Associated types could be anything, I guess.
|
||||
ty::ty_projection(..) => {
|
||||
false
|
||||
}
|
||||
|
||||
ty::ty_unboxed_closure(..) |
|
||||
ty::ty_infer(..) |
|
||||
ty::ty_open(..) |
|
||||
ty::ty_err => {
|
||||
@ -165,3 +152,27 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn type_parameters_covered_by_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||
ty: Ty<'tcx>)
|
||||
-> HashSet<ty::ParamTy>
|
||||
{
|
||||
if ty_is_local_constructor(tcx, ty) {
|
||||
type_parameters_reachable_from_ty(ty)
|
||||
} else {
|
||||
ty.walk_children().flat_map(|t| type_parameters_covered_by_ty(tcx, t).into_iter()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// All type parameters reachable from `ty`
|
||||
fn type_parameters_reachable_from_ty<'tcx>(ty: Ty<'tcx>) -> HashSet<ty::ParamTy> {
|
||||
ty.walk()
|
||||
.filter_map(|t| {
|
||||
match t.sty {
|
||||
ty::ty_param(ref param_ty) => Some(param_ty.clone()),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@
|
||||
use util::ppaux::Repr;
|
||||
|
||||
pub use self::error_reporting::report_fulfillment_errors;
|
||||
pub use self::coherence::orphan_check;
|
||||
pub use self::coherence::OrphanCheckErr;
|
||||
pub use self::fulfill::{FulfillmentContext, RegionObligation};
|
||||
pub use self::project::MismatchedProjectionTypes;
|
||||
pub use self::project::normalize;
|
||||
@ -245,15 +247,6 @@ pub struct VtableBuiltinData<N> {
|
||||
pub nested: subst::VecPerParamSpace<N>
|
||||
}
|
||||
|
||||
/// True if neither the trait nor self type is local. Note that `impl_def_id` must refer to an impl
|
||||
/// of a trait, not an inherent impl.
|
||||
pub fn is_orphan_impl(tcx: &ty::ctxt,
|
||||
impl_def_id: ast::DefId)
|
||||
-> bool
|
||||
{
|
||||
!coherence::impl_is_local(tcx, impl_def_id)
|
||||
}
|
||||
|
||||
/// True if there exist types that satisfy both of the two given impls.
|
||||
pub fn overlapping_impls(infcx: &InferCtxt,
|
||||
impl1_def_id: ast::DefId,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#![allow(unknown_features)]
|
||||
#![feature(globs, phase, macro_rules, slicing_syntax)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
#[phase(plugin, link)]
|
||||
extern crate log;
|
||||
|
@ -16,10 +16,12 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(default_type_params, globs, macro_rules, phase, quote)]
|
||||
#![feature(slicing_syntax, unsafe_destructor)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#[phase(plugin, link)] extern crate log;
|
||||
|
@ -22,10 +22,12 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(default_type_params, globs, macro_rules, phase, quote)]
|
||||
#![feature(slicing_syntax, unsafe_destructor)]
|
||||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate flate;
|
||||
|
@ -18,7 +18,7 @@
|
||||
use syntax::ast_util;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::visit;
|
||||
use util::ppaux::Repr;
|
||||
use util::ppaux::{Repr, UserString};
|
||||
|
||||
pub fn check(tcx: &ty::ctxt) {
|
||||
let mut orphan = OrphanChecker { tcx: tcx };
|
||||
@ -67,10 +67,27 @@ fn visit_item(&mut self, item: &'v ast::Item) {
|
||||
ast::ItemImpl(_, _, Some(_), _, _) => {
|
||||
// "Trait" impl
|
||||
debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
|
||||
if traits::is_orphan_impl(self.tcx, def_id) {
|
||||
span_err!(self.tcx.sess, item.span, E0117,
|
||||
"cannot provide an extension implementation \
|
||||
where both trait and type are not defined in this crate");
|
||||
match traits::orphan_check(self.tcx, def_id) {
|
||||
Ok(()) => { }
|
||||
Err(traits::OrphanCheckErr::NoLocalInputType) => {
|
||||
span_err!(self.tcx.sess, item.span, E0117,
|
||||
"cannot provide an extension implementation \
|
||||
where both trait and type are not defined in this crate");
|
||||
}
|
||||
Err(traits::OrphanCheckErr::UncoveredTypeParameter(param_ty)) => {
|
||||
if !self.tcx.sess.features.borrow().old_orphan_check {
|
||||
self.tcx.sess.span_err(
|
||||
item.span,
|
||||
format!("type parameter `{}` must also appear as a type parameter \
|
||||
of some type defined within this crate",
|
||||
param_ty.user_string(self.tcx)).as_slice());
|
||||
self.tcx.sess.span_note(
|
||||
item.span,
|
||||
format!("for a limited time, you can add \
|
||||
`#![feature(old_orphan_check)]` to your crate \
|
||||
to disable this rule").as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#![allow(unknown_features)]
|
||||
#![feature(globs, macro_rules, phase, slicing_syntax)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate getopts;
|
||||
|
@ -81,7 +81,7 @@
|
||||
//! use serialize::json;
|
||||
//!
|
||||
//! // Automatically generate `Decodable` and `Encodable` trait implementations
|
||||
//! #[deriving(Decodable, Encodable)]
|
||||
//! #[deriving(RustcDecodable, RustcEncodable)]
|
||||
//! pub struct TestStruct {
|
||||
//! data_int: u8,
|
||||
//! data_str: String,
|
||||
|
@ -107,6 +107,7 @@
|
||||
#![feature(macro_rules, globs, linkage, thread_local, asm)]
|
||||
#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
|
||||
#![feature(slicing_syntax, unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
// Don't link to std. We are std.
|
||||
#![no_std]
|
||||
|
@ -77,8 +77,11 @@
|
||||
// to bootstrap fix for #5723.
|
||||
("issue_5723_bootstrap", Accepted),
|
||||
|
||||
// A way to temporary opt out of opt in copy. This will *never* be accepted.
|
||||
("opt_out_copy", Active),
|
||||
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
|
||||
("opt_out_copy", Deprecated),
|
||||
|
||||
// A way to temporarily opt out of the new orphan rules. This will *never* be accepted.
|
||||
("old_orphan_check", Deprecated),
|
||||
|
||||
// These are used to test this portion of the compiler, they don't actually
|
||||
// mean anything
|
||||
@ -91,6 +94,10 @@ enum Status {
|
||||
/// currently being considered for addition/removal.
|
||||
Active,
|
||||
|
||||
/// Represents a feature gate that is temporarily enabling deprecated behavior.
|
||||
/// This gate will never be accepted.
|
||||
Deprecated,
|
||||
|
||||
/// Represents a feature which has since been removed (it was once Active)
|
||||
Removed,
|
||||
|
||||
@ -108,6 +115,7 @@ pub struct Features {
|
||||
pub visible_private_types: bool,
|
||||
pub quote: bool,
|
||||
pub opt_out_copy: bool,
|
||||
pub old_orphan_check: bool,
|
||||
}
|
||||
|
||||
impl Features {
|
||||
@ -120,6 +128,7 @@ pub fn new() -> Features {
|
||||
visible_private_types: false,
|
||||
quote: false,
|
||||
opt_out_copy: false,
|
||||
old_orphan_check: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -442,7 +451,16 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
|
||||
};
|
||||
match KNOWN_FEATURES.iter()
|
||||
.find(|& &(n, _)| name == n) {
|
||||
Some(&(name, Active)) => { cx.features.push(name); }
|
||||
Some(&(name, Active)) => {
|
||||
cx.features.push(name);
|
||||
}
|
||||
Some(&(name, Deprecated)) => {
|
||||
cx.features.push(name);
|
||||
span_handler.span_warn(
|
||||
mi.span,
|
||||
"feature is deprecated and will only be available \
|
||||
for a limited time, please rewrite code that relies on it");
|
||||
}
|
||||
Some(&(_, Removed)) => {
|
||||
span_handler.span_err(mi.span, "feature has been removed");
|
||||
}
|
||||
@ -469,6 +487,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
|
||||
visible_private_types: cx.has_feature("visible_private_types"),
|
||||
quote: cx.has_feature("quote"),
|
||||
opt_out_copy: cx.has_feature("opt_out_copy"),
|
||||
old_orphan_check: cx.has_feature("old_orphan_check"),
|
||||
},
|
||||
unknown_features)
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#![feature(macro_rules, globs, default_type_params, phase, slicing_syntax)]
|
||||
#![feature(quote, unsafe_destructor)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate fmt_macros;
|
||||
|
@ -31,8 +31,10 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(asm, macro_rules, phase, globs, slicing_syntax)]
|
||||
#![feature(unboxed_closures, default_type_params)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate getopts;
|
||||
extern crate regex;
|
||||
|
@ -20,7 +20,10 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/",
|
||||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(phase, globs)]
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
#[cfg(test)] #[phase(plugin, link)] extern crate log;
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(opt_out_copy)]
|
||||
//~^ WARNING feature is deprecated
|
||||
//~| WARNING feature is deprecated
|
||||
|
||||
// Test that when using the `opt-out-copy` feature we still consider
|
||||
// destructors to be non-movable
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
|
||||
use serialize::{Encodable, Decodable};
|
||||
|
@ -11,6 +11,8 @@
|
||||
// This briefly tests the capability of `Cell` and `RefCell` to implement the
|
||||
// `Encodable` and `Decodable` traits via `#[deriving(Encodable, Decodable)]`
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
extern crate rand;
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate rbml;
|
||||
extern crate serialize;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
extern crate serialize;
|
||||
|
||||
|
@ -8,6 +8,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// If `Index` used an associated type for its output, this test would
|
||||
// work more smoothly.
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
struct Mat<T> { data: Vec<T>, cols: uint, }
|
||||
|
||||
impl<T> Mat<T> {
|
||||
|
@ -8,6 +8,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// If `Mul` used an associated type for its output, this test would
|
||||
// work more smoothly.
|
||||
#![feature(old_orphan_check)]
|
||||
|
||||
struct Vec2 {
|
||||
x: f64,
|
||||
y: f64
|
||||
|
@ -14,9 +14,9 @@
|
||||
|
||||
use std::ops::Fn;
|
||||
|
||||
struct G;
|
||||
struct G<A>;
|
||||
|
||||
impl<'a, A: Add<int, int>> Fn<(A,), int> for G {
|
||||
impl<'a, A: Add<int, int>> Fn<(A,), int> for G<A> {
|
||||
extern "rust-call" fn call(&self, (arg,): (A,)) -> int {
|
||||
arg.add(1)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user