From c61a0092bc236c4be4cb691fcd50ff50e91ab0d6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 26 Dec 2014 03:30:51 -0500 Subject: [PATCH] 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 { ... } // Here `T` appears "under' `MyStruct`. impl Clone for MyStruct { } // Here `T` appears "under' `MyStruct` as well. Note that it also appears // elsewhere. impl Iterator for MyStruct { } ``` Here is an illegal example: ```rust // Here `U` does not appear "under" `MyStruct` or any other local type. // We call `U` "uncovered". impl Iterator for MyStruct { } ``` 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 { ... } impl Iterator for MyStruct { } ``` 3. Create a newtype wrapper for `U` ```rust impl Iterator> for MyStruct { } ``` 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. --- src/liballoc/lib.rs | 3 +- src/libcollections/lib.rs | 1 + src/libgraphviz/maybe_owned_vec.rs | 6 +- src/librustc/lib.rs | 2 + src/librustc/middle/traits/coherence.rs | 155 ++++++++++-------- src/librustc/middle/traits/mod.rs | 11 +- src/librustc_back/lib.rs | 1 + src/librustc_borrowck/lib.rs | 2 + src/librustc_trans/lib.rs | 2 + src/librustc_typeck/coherence/orphan.rs | 27 ++- src/librustdoc/lib.rs | 1 + src/libserialize/json.rs | 2 +- src/libstd/lib.rs | 1 + src/libsyntax/feature_gate.rs | 25 ++- src/libsyntax/lib.rs | 1 + src/libtest/lib.rs | 2 + src/libtime/lib.rs | 3 + src/test/compile-fail/opt-out-copy-bad.rs | 2 + .../deriving-encodable-decodable-box.rs | 2 + ...riving-encodable-decodable-cell-refcell.rs | 2 + src/test/run-pass/deriving-global.rs | 2 + src/test/run-pass/issue-11881.rs | 2 + src/test/run-pass/issue-14021.rs | 1 + src/test/run-pass/issue-15734.rs | 4 + src/test/run-pass/issue-3743.rs | 4 + .../overloaded-calls-param-vtables.rs | 4 +- 26 files changed, 172 insertions(+), 96 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 61b5d43d1cb..d17a54ce6e5 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -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; diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 688214140c1..b7307cfb7fb 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -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; diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index ddda2b38c22..c9943562c88 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -96,9 +96,9 @@ fn cmp(&self, other: &MaybeOwnedVector) -> Ordering { } #[allow(deprecated)] -impl<'a, T: PartialEq, Sized? V: AsSlice> Equiv 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 } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 3d99a880f68..cdc27244dde 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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; diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index d8b39d92c69..4aff36c2624 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -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 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 is bivariant with respect to - // T, then it doesn't matter whether T is - // local or not, because `Foo` 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 +{ + 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.walk() + .filter_map(|t| { + match t.sty { + ty::ty_param(ref param_ty) => Some(param_ty.clone()), + _ => None, + } + }) + .collect() +} + diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index b10dfa5b718..fc2eb43c8a5 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -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 { pub nested: subst::VecPerParamSpace } -/// 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, diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index cb547df7d9c..2bb99a7141f 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -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; diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 664d470b11b..b886883c73a 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -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; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 784002287b7..5ffe9b2d647 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -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; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 79443200ddf..44b27ec2e12 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -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()); + } + } } } _ => { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ccdc8164255..e1d9ebd7aa2 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -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; diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 3f0d59c319a..684856ae33b 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -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, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 74c387c5eea..9e8fba21df5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -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] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b2c2d7eb626..23c4ee8f64b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -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(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(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) } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index d5093c5055c..7a6824ac27c 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -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; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index c097e933790..e61de01e0ac 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -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; diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index 87a00334c47..b5976c46a7d 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -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; diff --git a/src/test/compile-fail/opt-out-copy-bad.rs b/src/test/compile-fail/opt-out-copy-bad.rs index 80f8a154d58..4aae8fa87da 100644 --- a/src/test/compile-fail/opt-out-copy-bad.rs +++ b/src/test/compile-fail/opt-out-copy-bad.rs @@ -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 diff --git a/src/test/run-pass/deriving-encodable-decodable-box.rs b/src/test/run-pass/deriving-encodable-decodable-box.rs index e21f64cd74c..a24ae22b224 100644 --- a/src/test/run-pass/deriving-encodable-decodable-box.rs +++ b/src/test/run-pass/deriving-encodable-decodable-box.rs @@ -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}; diff --git a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs index a846f852694..f5df1940fa4 100644 --- a/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs +++ b/src/test/run-pass/deriving-encodable-decodable-cell-refcell.rs @@ -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}; diff --git a/src/test/run-pass/deriving-global.rs b/src/test/run-pass/deriving-global.rs index 2322675661c..9ece4af278b 100644 --- a/src/test/run-pass/deriving-global.rs +++ b/src/test/run-pass/deriving-global.rs @@ -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; diff --git a/src/test/run-pass/issue-11881.rs b/src/test/run-pass/issue-11881.rs index 8de847bfa33..10370ba22c8 100644 --- a/src/test/run-pass/issue-11881.rs +++ b/src/test/run-pass/issue-11881.rs @@ -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; diff --git a/src/test/run-pass/issue-14021.rs b/src/test/run-pass/issue-14021.rs index a55cded87e5..39b4a726d45 100644 --- a/src/test/run-pass/issue-14021.rs +++ b/src/test/run-pass/issue-14021.rs @@ -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; diff --git a/src/test/run-pass/issue-15734.rs b/src/test/run-pass/issue-15734.rs index ea5bd550d53..72123b8e5a5 100644 --- a/src/test/run-pass/issue-15734.rs +++ b/src/test/run-pass/issue-15734.rs @@ -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 { data: Vec, cols: uint, } impl Mat { diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs index 80d3d29bc00..ac200c81143 100644 --- a/src/test/run-pass/issue-3743.rs +++ b/src/test/run-pass/issue-3743.rs @@ -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 diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs index 2e8ec3916bd..96420f17deb 100644 --- a/src/test/run-pass/overloaded-calls-param-vtables.rs +++ b/src/test/run-pass/overloaded-calls-param-vtables.rs @@ -14,9 +14,9 @@ use std::ops::Fn; -struct G; +struct G; -impl<'a, A: Add> Fn<(A,), int> for G { +impl<'a, A: Add> Fn<(A,), int> for G { extern "rust-call" fn call(&self, (arg,): (A,)) -> int { arg.add(1) }