diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 61b5d43d1cb5011449f3e216135d14ff73a3112f..d17a54ce6e56d8bb5f208b512f2a13f4ab42ecd8 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 cbd8d4955b217441ec48f79ade77b68494cd78ea..82175c3949466c0d3315d5a5e409ef2ba91873d7 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 573f0926e29150035e684539f5b3bb2d995faa02..d0396ddc7adcc21504039c20f8a9f484a0e2e08a 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -98,9 +98,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 4647c92e3d1e8a09e25d7e8098acaf593a63f027..cdc27244dde6ea6dde1650a75750bf0fd5944939 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; @@ -98,6 +100,7 @@ pub mod middle { pub mod traits; pub mod ty; pub mod ty_fold; + pub mod ty_walk; pub mod weak_lang_items; } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 0917135bee9a1d8052e22b475405fdb5139d7f2c..a25b6d8b8fa4688a0821bc8285699ba4188e41c3 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -443,9 +443,15 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd, -> Option>> { let item_doc = lookup_item(id, cdata.data()); - reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| { - doc_trait_ref(tp, tcx, cdata) - }) + let fam = item_family(item_doc); + match fam { + Family::Impl => { + reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| { + doc_trait_ref(tp, tcx, cdata) + }) + } + _ => None + } } pub fn get_impl_vtables<'tcx>(cdata: Cmd, diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index d793f49efe5e8cf640d608d99cdf4261015816d3..505352fa1234462801e06c5d95abbece2acce6d7 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -11,7 +11,8 @@ //! A pass that annotates every item and method with its stability level, //! propagating default levels lexically from parent to children ast nodes. -use util::nodemap::{NodeMap, DefIdMap}; +use middle::ty; +use metadata::csearch; use syntax::codemap::Span; use syntax::{attr, visit}; use syntax::ast; @@ -21,8 +22,8 @@ use syntax::ast_util::is_local; use syntax::attr::Stability; use syntax::visit::{FnKind, FkMethod, Visitor}; -use middle::ty; -use metadata::csearch; +use util::nodemap::{NodeMap, DefIdMap}; +use util::ppaux::Repr; use std::mem::replace; @@ -154,10 +155,13 @@ pub fn build(krate: &Crate) -> Index { /// Lookup the stability for a node, loading external crate /// metadata as necessary. pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option { + debug!("lookup(id={})", + id.repr(tcx)); + // is this definition the implementation of a trait method? match ty::trait_item_of_item(tcx, id) { - Some(ty::MethodTraitItemId(trait_method_id)) - if trait_method_id != id => { + Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => { + debug!("lookup: trait_method_id={}", trait_method_id); return lookup(tcx, trait_method_id) } _ => {} @@ -178,6 +182,7 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option { // stability of the trait to determine the stability of any // unmarked impls for it. See FIXME above for more details. + debug!("lookup: trait_id={}", trait_id); lookup(tcx, trait_id) } else { None diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index d8b39d92c692fad9ca0c392338ce1db322ef18ed..4aff36c2624958764c83996cbe82af71f682efaa 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(()); +} + +fn ty_reaches_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { + ty.walk().any(|t| ty_is_local_constructor(tcx, t)) } -pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { - debug!("ty_is_local({})", ty.repr(tcx)); +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) => { - 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, _) | + ty::ty_struct(def_id, _) => { + def_id.krate == ast::LOCAL_CRATE } - 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) - } - } - }) - }) - } + ty::ty_uniq(_) => { // treat ~T like Box + let krate = tcx.lang_items.owned_box().map(|d| d.krate); + 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 b10dfa5b718136ca058ec4844920cc2266d20f72..fc2eb43c8a5ffec84396136837659a89ddc0571e 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/middle/ty.rs b/src/librustc/middle/ty.rs index e699ee2ec91452cd233f74826bef776cf3c1cbcd..26a9cc5464e9549ff7bc6450a34b8d63c8535d5e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -59,6 +59,7 @@ use middle::traits; use middle::ty; use middle::ty_fold::{mod, TypeFoldable, TypeFolder}; +use middle::ty_walk::TypeWalker; use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string}; use util::ppaux::{trait_store_to_string, ty_to_string}; use util::ppaux::{Repr, UserString}; @@ -2831,59 +2832,61 @@ pub fn mk_param_from_def<'tcx>(cx: &ctxt<'tcx>, def: &TypeParameterDef) -> Ty<'t pub fn mk_open<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_open(ty)) } -pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where - F: FnMut(Ty<'tcx>), +impl<'tcx> TyS<'tcx> { + /// Iterator that walks `self` and any types reachable from + /// `self`, in depth-first order. Note that just walks the types + /// that appear in `self`, it does not descend into the fields of + /// structs or variants. For example: + /// + /// ```notrust + /// int => { int } + /// Foo> => { Foo>, Bar, int } + /// [int] => { [int], int } + /// ``` + pub fn walk(&'tcx self) -> TypeWalker<'tcx> { + TypeWalker::new(self) + } + + /// Iterator that walks types reachable from `self`, in + /// depth-first order. Note that this is a shallow walk. For + /// example: + /// + /// ```notrust + /// int => { } + /// Foo> => { Bar, int } + /// [int] => { int } + /// ``` + pub fn walk_children(&'tcx self) -> TypeWalker<'tcx> { + // Walks type reachable from `self` but not `self + let mut walker = self.walk(); + let r = walker.next(); + assert_eq!(r, Some(self)); + walker + } +} + +pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F) + where F: FnMut(Ty<'tcx>), { - maybe_walk_ty(ty, |ty| { f(ty); true }); + for ty in ty_root.walk() { + f(ty); + } } -pub fn maybe_walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where F: FnMut(Ty<'tcx>) -> bool { - // FIXME(#19596) This is a workaround, but there should be a better way to do this - fn maybe_walk_ty_<'tcx, F>(ty: Ty<'tcx>, f: &mut F) where F: FnMut(Ty<'tcx>) -> bool { - if !(*f)(ty) { - return; - } - match ty.sty { - ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) | - ty_str | ty_infer(_) | ty_param(_) | ty_err => {} - ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty_(ty, f), - ty_ptr(ref tm) | ty_rptr(_, ref tm) => { - maybe_walk_ty_(tm.ty, f); - } - ty_trait(box TyTrait { ref principal, .. }) => { - for subty in principal.0.substs.types.iter() { - maybe_walk_ty_(*subty, f); - } - } - ty_projection(ProjectionTy { ref trait_ref, .. }) => { - for subty in trait_ref.substs.types.iter() { - maybe_walk_ty_(*subty, f); - } - } - ty_enum(_, ref substs) | - ty_struct(_, ref substs) | - ty_unboxed_closure(_, _, ref substs) => { - for subty in substs.types.iter() { - maybe_walk_ty_(*subty, f); - } - } - ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty_(*tt, f); } } - ty_bare_fn(_, ref ft) => { - for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); } - if let ty::FnConverging(output) = ft.sig.0.output { - maybe_walk_ty_(output, f); - } - } - ty_closure(ref ft) => { - for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); } - if let ty::FnConverging(output) = ft.sig.0.output { - maybe_walk_ty_(output, f); - } - } +/// Walks `ty` and any types appearing within `ty`, invoking the +/// callback `f` on each type. If the callback returns false, then the +/// children of the current type are ignored. +/// +/// Note: prefer `ty.walk()` where possible. +pub fn maybe_walk_ty<'tcx,F>(ty_root: Ty<'tcx>, mut f: F) + where F : FnMut(Ty<'tcx>) -> bool +{ + let mut walker = ty_root.walk(); + while let Some(ty) = walker.next() { + if !f(ty) { + walker.skip_current_subtree(); } } - - maybe_walk_ty_(ty, &mut f); } // Folds types from the bottom up. @@ -6122,22 +6125,9 @@ pub fn populate_implementations_for_trait_if_necessary( /// Given the def_id of an impl, return the def_id of the trait it implements. /// If it implements no trait, return `None`. pub fn trait_id_of_impl(tcx: &ctxt, - def_id: ast::DefId) -> Option { - let node = match tcx.map.find(def_id.node) { - Some(node) => node, - None => return None - }; - match node { - ast_map::NodeItem(item) => { - match item.node { - ast::ItemImpl(_, _, Some(ref trait_ref), _, _) => { - Some(node_id_to_trait_ref(tcx, trait_ref.ref_id).def_id) - } - _ => None - } - } - _ => None - } + def_id: ast::DefId) + -> Option { + ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id) } /// If the given def ID describes a method belonging to an impl, return the diff --git a/src/librustc/middle/ty_walk.rs b/src/librustc/middle/ty_walk.rs new file mode 100644 index 0000000000000000000000000000000000000000..406ebf4bc38a40288f08ac3e234b653e9a0dd6b4 --- /dev/null +++ b/src/librustc/middle/ty_walk.rs @@ -0,0 +1,112 @@ +// Copyright 2012-2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! An iterator over the type substructure. + +use middle::ty::{mod, Ty}; +use std::iter::Iterator; + +pub struct TypeWalker<'tcx> { + stack: Vec>, + last_subtree: uint, +} + +impl<'tcx> TypeWalker<'tcx> { + pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> { + TypeWalker { stack: vec!(ty), last_subtree: 1, } + } + + fn push_subtypes(&mut self, parent_ty: Ty<'tcx>) { + match parent_ty.sty { + ty::ty_bool | ty::ty_char | ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) | + ty::ty_str | ty::ty_infer(_) | ty::ty_param(_) | ty::ty_err => { + } + ty::ty_uniq(ty) | ty::ty_vec(ty, _) | ty::ty_open(ty) => { + self.stack.push(ty); + } + ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => { + self.stack.push(mt.ty); + } + ty::ty_projection(ref data) => { + self.push_reversed(data.trait_ref.substs.types.as_slice()); + } + ty::ty_trait(box ty::TyTrait { ref principal, .. }) => { + self.push_reversed(principal.substs().types.as_slice()); + } + ty::ty_enum(_, ref substs) | + ty::ty_struct(_, ref substs) | + ty::ty_unboxed_closure(_, _, ref substs) => { + self.push_reversed(substs.types.as_slice()); + } + ty::ty_tup(ref ts) => { + self.push_reversed(ts.as_slice()); + } + ty::ty_bare_fn(_, ref ft) => { + self.push_sig_subtypes(&ft.sig); + } + ty::ty_closure(ref ft) => { + self.push_sig_subtypes(&ft.sig); + } + } + } + + fn push_sig_subtypes(&mut self, sig: &ty::PolyFnSig<'tcx>) { + match sig.0.output { + ty::FnConverging(output) => { self.stack.push(output); } + ty::FnDiverging => { } + } + self.push_reversed(sig.0.inputs.as_slice()); + } + + fn push_reversed(&mut self, tys: &[Ty<'tcx>]) { + // We push slices on the stack in reverse order so as to + // maintain a pre-order traversal. As of the time of this + // writing, the fact that the traversal is pre-order is not + // known to be significant to any code, but it seems like the + // natural order one would expect (basically, the order of the + // types as they are written). + for &ty in tys.iter().rev() { + self.stack.push(ty); + } + } + + /// Skips the subtree of types corresponding to the last type + /// returned by `next()`. + /// + /// Example: Imagine you are walking `Foo, uint>`. + /// + /// ```rust + /// let mut iter: TypeWalker = ...; + /// iter.next(); // yields Foo + /// iter.next(); // yields Bar + /// iter.skip_current_subtree(); // skips int + /// iter.next(); // yields uint + /// ``` + pub fn skip_current_subtree(&mut self) { + self.stack.truncate(self.last_subtree); + } +} + +impl<'tcx> Iterator> for TypeWalker<'tcx> { + fn next(&mut self) -> Option> { + debug!("next(): stack={}", self.stack); + match self.stack.pop() { + None => { + return None; + } + Some(ty) => { + self.last_subtree = self.stack.len(); + self.push_subtypes(ty); + debug!("next: stack={}", self.stack); + Some(ty) + } + } + } +} diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index cb547df7d9cd83a9cc8a710eb586730431d2e899..2bb99a7141f7098c8d74ad9375eb66ad193ce83e 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 664d470b11bd1c46ad6a228946272b712f8ad6f5..b886883c73ad21c989cf14d10f0d6e9e8c401f35 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_driver/test.rs b/src/librustc_driver/test.rs index 6329acfb57805c5372a30eeed9dfd99199c76ada..eddcc75006899bf74bfda8acc8cd238ae283bd1b 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -34,8 +34,6 @@ use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help}; use syntax::parse::token; -use arena::TypedArena; - struct Env<'a, 'tcx: 'a> { infcx: &'a infer::InferCtxt<'a, 'tcx>, } @@ -831,3 +829,57 @@ fn subst_region_renumber_region() { assert_eq!(t_substituted, t_expected); }) } + +#[test] +fn walk_ty() { + test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + let tcx = env.infcx.tcx; + let int_ty = tcx.types.int; + let uint_ty = tcx.types.uint; + let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty)); + let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty)); + let uniq_ty = ty::mk_uniq(tcx, tup2_ty); + let walked: Vec<_> = uniq_ty.walk().collect(); + assert_eq!(vec!(uniq_ty, + tup2_ty, + tup1_ty, int_ty, uint_ty, int_ty, uint_ty, + tup1_ty, int_ty, uint_ty, int_ty, uint_ty, + uint_ty), + walked); + }) +} + +#[test] +fn walk_ty_skip_subtree() { + test_env(EMPTY_SOURCE_STR, errors(&[]), |env| { + let tcx = env.infcx.tcx; + let int_ty = tcx.types.int; + let uint_ty = tcx.types.uint; + let tup1_ty = ty::mk_tup(tcx, vec!(int_ty, uint_ty, int_ty, uint_ty)); + let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty)); + let uniq_ty = ty::mk_uniq(tcx, tup2_ty); + + // types we expect to see (in order), plus a boolean saying + // whether to skip the subtree. + let mut expected = vec!((uniq_ty, false), + (tup2_ty, false), + (tup1_ty, false), + (int_ty, false), + (uint_ty, false), + (int_ty, false), + (uint_ty, false), + (tup1_ty, true), // skip the int/uint/int/uint + (uint_ty, false)); + expected.reverse(); + + let mut walker = uniq_ty.walk(); + while let Some(t) = walker.next() { + debug!("walked to {}", t); + let (expected_ty, skip) = expected.pop().unwrap(); + assert_eq!(t, expected_ty); + if skip { walker.skip_current_subtree(); } + } + + assert!(expected.is_empty()); + }) +} diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 784002287b7502ee2c99e87bf7785675eced0e63..5ffe9b2d6471acc1a2ceaa5d20a1f69f1ec073a9 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 49f150cf027d5d17f015892a53b7bdab2b3554c3..1da49799712bd6e3166639e85819b35fe57688da 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 }; @@ -72,10 +72,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 8eb4448c649b1555bc62281e44b3704fa323c68e..1beeeaf629dbf0e724acd1ab807ce91deeac363c 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 2c83807aa4f53ee9c18ee9cf34746d9877cddf28..e0122ad106fa07c2a7c9d0ddf79b15bae787aa2d 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -76,12 +76,13 @@ //! Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the //! serialization API, using the derived serialization code. //! -//! ```rust +//! ```notrust +//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment //! extern crate serialize; //! 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, @@ -110,7 +111,8 @@ //! //! ### Simple example of `ToJson` usage //! -//! ```rust +//! ```notrust +//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment //! extern crate serialize; //! use serialize::json::{mod, ToJson, Json}; //! @@ -149,7 +151,8 @@ //! //! ### Verbose example of `ToJson` usage //! -//! ```rust +//! ```notrust +//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment //! extern crate serialize; //! use std::collections::BTreeMap; //! use serialize::json::{mod, Json, ToJson}; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 6187593afd188438e85384c1a0b178be1f003424..848d3604953ead44e3043e8a889e497fc22f36e1 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 035b748a7db47b48eb60e36de46121b06d69b067..545856a27af4ccd81b911f818d091581485a051a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -78,8 +78,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 @@ -92,6 +95,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, @@ -109,6 +116,7 @@ pub struct Features { pub visible_private_types: bool, pub quote: bool, pub opt_out_copy: bool, + pub old_orphan_check: bool, } impl Features { @@ -121,6 +129,7 @@ pub fn new() -> Features { visible_private_types: false, quote: false, opt_out_copy: false, + old_orphan_check: false, } } } @@ -453,7 +462,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"); } @@ -480,6 +498,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 d5093c5055c79251956e391d1feb5f802d3ff28e..7a6824ac27c658cbfc256f664376c42faa76c071 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 2ea5ee3e16d1821c9b1306e9d7b79e54a2ce8847..b2d3611fc64fcb0d76614fc546d6cca05f0d4dcc 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 d9db2d80adaff4714207720b566b5bb477d0c232..bc5d0c21aaeb466c63c9e9cedf2621688a7ee6be 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/auxiliary/coherence-lib.rs b/src/test/auxiliary/coherence-lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..daa123849e4e797d539db3433a7908c97f18887f --- /dev/null +++ b/src/test/auxiliary/coherence-lib.rs @@ -0,0 +1,25 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type="lib"] + +pub trait Remote { + fn foo(&self) { } +} + +pub trait Remote1 { + fn foo(&self, t: T) { } +} + +pub trait Remote2 { + fn foo(&self, t: T, u: U) { } +} + +pub struct Pair(T,U); diff --git a/src/test/compile-fail/coherence-all-remote.rs b/src/test/compile-fail/coherence-all-remote.rs new file mode 100644 index 0000000000000000000000000000000000000000..67d96aa95a6a2513ba59bb831b1f3512c03a48e1 --- /dev/null +++ b/src/test/compile-fail/coherence-all-remote.rs @@ -0,0 +1,19 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote; + +impl Remote for int { } +//~^ ERROR cannot provide an extension implementation + +fn main() { } diff --git a/src/test/compile-fail/coherence-bigint-param.rs b/src/test/compile-fail/coherence-bigint-param.rs new file mode 100644 index 0000000000000000000000000000000000000000..a04dfd36c98f175e3acaac0f414785ac5cfa02be --- /dev/null +++ b/src/test/compile-fail/coherence-bigint-param.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1 for T { } +//~^ ERROR type parameter `T` must also appear + +fn main() { } diff --git a/src/test/compile-fail/coherence-iterator-vec-any-elem.rs b/src/test/compile-fail/coherence-iterator-vec-any-elem.rs new file mode 100644 index 0000000000000000000000000000000000000000..2ed7a6db7ae1cf426e5fa5dbb1af7c9dbc7f1aa3 --- /dev/null +++ b/src/test/compile-fail/coherence-iterator-vec-any-elem.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote1; + +struct Foo(T); + +impl Remote1 for Foo { } +//~^ ERROR type parameter `U` must also appear + +fn main() { } diff --git a/src/test/compile-fail/coherence-lone-type-parameter.rs b/src/test/compile-fail/coherence-lone-type-parameter.rs new file mode 100644 index 0000000000000000000000000000000000000000..0223dacd8eca0754761e73fa2a06fc448de8f730 --- /dev/null +++ b/src/test/compile-fail/coherence-lone-type-parameter.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote; + +impl Remote for T { } //~ ERROR E0117 + +fn main() { } diff --git a/src/test/compile-fail/coherence-overlapping-pairs.rs b/src/test/compile-fail/coherence-overlapping-pairs.rs new file mode 100644 index 0000000000000000000000000000000000000000..d42bd529b6665bd12cf12c801501b70eb21b0fc9 --- /dev/null +++ b/src/test/compile-fail/coherence-overlapping-pairs.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote; + +struct Foo; + +impl Remote for lib::Pair { } +//~^ ERROR type parameter `T` must also appear + +fn main() { } diff --git a/src/test/compile-fail/coherence-pair-covered-uncovered.rs b/src/test/compile-fail/coherence-pair-covered-uncovered.rs new file mode 100644 index 0000000000000000000000000000000000000000..09895ec11db108529a20fe7955904a574c3b8b77 --- /dev/null +++ b/src/test/compile-fail/coherence-pair-covered-uncovered.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::{Remote, Pair}; + +struct Local(T); + +impl Remote for Pair> { } +//~^ ERROR type parameter `T` must also appear + +fn main() { } diff --git a/src/test/compile-fail/opt-out-copy-bad.rs b/src/test/compile-fail/opt-out-copy-bad.rs index 80f8a154d58e47170027199a74428947128984bc..4aae8fa87daffbd7e6abcd8eb6e1ccf4ddbb6b4f 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/coherence-bigint-int.rs b/src/test/run-pass/coherence-bigint-int.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e90453980f8687adc35bd1aec7d9cc47f28b0a1 --- /dev/null +++ b/src/test/run-pass/coherence-bigint-int.rs @@ -0,0 +1,20 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1 for int { } + +fn main() { } diff --git a/src/test/run-pass/coherence-bigint-vecint.rs b/src/test/run-pass/coherence-bigint-vecint.rs new file mode 100644 index 0000000000000000000000000000000000000000..b100455eb339c0c86a6c280382a1b32046b7e6d6 --- /dev/null +++ b/src/test/run-pass/coherence-bigint-vecint.rs @@ -0,0 +1,20 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote1; + +pub struct BigInt; + +impl Remote1 for Vec { } + +fn main() { } diff --git a/src/test/run-pass/coherence-blanket.rs b/src/test/run-pass/coherence-blanket.rs new file mode 100644 index 0000000000000000000000000000000000000000..e02117d1ca261f02b0c751c43d6ddb5b8189a76b --- /dev/null +++ b/src/test/run-pass/coherence-blanket.rs @@ -0,0 +1,22 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote1; + +pub trait Local { + fn foo(&self) { } +} + +impl Local for T { } + +fn main() { } diff --git a/src/test/run-pass/coherence-covered-type-parameter.rs b/src/test/run-pass/coherence-covered-type-parameter.rs new file mode 100644 index 0000000000000000000000000000000000000000..27f1f2dafb003628399c7cbfccdb9a5c0582ad97 --- /dev/null +++ b/src/test/run-pass/coherence-covered-type-parameter.rs @@ -0,0 +1,20 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote; + +struct Foo(T); + +impl Remote for Foo { } + +fn main() { } diff --git a/src/test/run-pass/coherence-iterator-vec.rs b/src/test/run-pass/coherence-iterator-vec.rs new file mode 100644 index 0000000000000000000000000000000000000000..7077503f73ff9353fc82f77d48039a8e82a8fa3e --- /dev/null +++ b/src/test/run-pass/coherence-iterator-vec.rs @@ -0,0 +1,20 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote1; + +struct Foo(T); + +impl Remote1 for Foo { } + +fn main() { } diff --git a/src/test/run-pass/coherence-local-1.rs b/src/test/run-pass/coherence-local-1.rs new file mode 100644 index 0000000000000000000000000000000000000000..a9bc3dc0e2f277b148664e0b507b6d1d1a9ae796 --- /dev/null +++ b/src/test/run-pass/coherence-local-1.rs @@ -0,0 +1,20 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote; + +struct Local; + +impl Remote for Vec { } + +fn main() { } diff --git a/src/test/run-pass/coherence-local-2.rs b/src/test/run-pass/coherence-local-2.rs new file mode 100644 index 0000000000000000000000000000000000000000..07a830cb1ac2daa75b545156d55e294642b4d5d8 --- /dev/null +++ b/src/test/run-pass/coherence-local-2.rs @@ -0,0 +1,20 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:coherence-lib.rs + +extern crate "coherence-lib" as lib; +use lib::Remote; + +struct Local(T); + +impl Remote for Vec> { } + +fn main() { } diff --git a/src/test/run-pass/deriving-encodable-decodable-box.rs b/src/test/run-pass/deriving-encodable-decodable-box.rs index e21f64cd74c80bc1bd04b00b4226098f5585ad64..a24ae22b224a3b223567e30fe2885d2784176091 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 a846f852694d336cdbe997dbcea08920c66c37e6..f5df1940fa47ea306301260afe69433e495da084 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 2322675661caf6af2dabc60b8fa41dba5741dea2..9ece4af278bdac2985db3030bf515619ea19943d 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 0e0aea081f634eb8ed08a66008d5a97109432959..06c637435551253d46a0e24ab8e523ebd4435895 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 a55cded87e51d51d5727cc795818ce1183dfafb1..39b4a726d4514557222b1851d3efd903bbdedf2d 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 8aa7447ccd2e90f787ee74f6b7cae63938f1df48..e99b1dc5befb00fdf1d2e11d80cc847b0516fe7c 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)] + use std::ops::Index; struct Mat { data: Vec, cols: uint, } diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs index c88022f3eb706ce28541d2958bb0c0cac9393298..cb4f1b7d20f14213b11434073d5c471755ad8589 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)] + use std::ops::Mul; struct Vec2 { diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs index 95df1ed0d837ed176e9536824f860a5a26eec7fe..bdaccee65d7f53bfeb208f99b02ae65f576ebd78 100644 --- a/src/test/run-pass/overloaded-calls-param-vtables.rs +++ b/src/test/run-pass/overloaded-calls-param-vtables.rs @@ -15,9 +15,9 @@ use std::ops::Fn; use std::ops::Add; -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) }