about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libarena/lib.rs5
-rw-r--r--src/libcore/marker.rs107
-rw-r--r--src/libcore/nonzero.rs1
-rw-r--r--src/librustc/middle/lang_items.rs1
-rw-r--r--src/librustc/middle/traits/object_safety.rs9
-rw-r--r--src/librustc/middle/traits/select.rs8
-rw-r--r--src/librustc/middle/ty_relate/mod.rs36
-rw-r--r--src/librustc_typeck/check/wf.rs42
-rw-r--r--src/librustc_typeck/variance.rs338
-rw-r--r--src/test/auxiliary/coherence_copy_like_lib.rs4
-rw-r--r--src/test/auxiliary/coherence_orphan_lib.rs2
-rw-r--r--src/test/auxiliary/lang-item-public.rs8
-rw-r--r--src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs6
-rw-r--r--src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs4
-rw-r--r--src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs4
-rw-r--r--src/test/compile-fail/issue-13853-2.rs4
-rw-r--r--src/test/compile-fail/issue-19660.rs6
-rw-r--r--src/test/compile-fail/kindck-impl-type-params.rs2
-rw-r--r--src/test/compile-fail/lint-unsafe-code.rs7
-rw-r--r--src/test/compile-fail/object-safety-phantom-fn.rs6
-rw-r--r--src/test/compile-fail/on-unimplemented-bad-anno.rs6
-rw-r--r--src/test/compile-fail/on-unimplemented.rs3
-rw-r--r--src/test/compile-fail/privacy1.rs8
-rw-r--r--src/test/compile-fail/privacy4.rs8
-rw-r--r--src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs4
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs4
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs4
-rw-r--r--src/test/compile-fail/regions-assoc-type-outlives-container.rs4
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-1.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-2.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-3.rs8
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-4.rs6
-rw-r--r--src/test/compile-fail/required-lang-item.rs6
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-1.rs3
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-2.rs1
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-equiv.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs2
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-object.rs6
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-trait-match.rs7
-rw-r--r--src/test/compile-fail/variance-contravariant-self-trait-match.rs8
-rw-r--r--src/test/compile-fail/variance-covariant-arg-object.rs6
-rw-r--r--src/test/compile-fail/variance-covariant-arg-trait-match.rs6
-rw-r--r--src/test/compile-fail/variance-covariant-self-trait-match.rs6
-rw-r--r--src/test/compile-fail/variance-region-bounds.rs4
-rw-r--r--src/test/compile-fail/variance-regions-unused-direct.rs2
-rw-r--r--src/test/compile-fail/variance-trait-bounds.rs10
-rw-r--r--src/test/compile-fail/variance-trait-matching.rs45
-rw-r--r--src/test/compile-fail/variance-types-bounds.rs10
-rw-r--r--src/test/compile-fail/variance-unused-region-param.rs2
-rw-r--r--src/test/compile-fail/variance-unused-type-param.rs4
-rw-r--r--src/test/run-make/simd-ffi/simd.rs8
-rw-r--r--src/test/run-make/target-specs/foo.rs8
-rw-r--r--src/test/run-pass/coherence-subtyping.rs (renamed from src/test/compile-fail/coherence-subtyping.rs)4
-rw-r--r--src/test/run-pass/coherence_copy_like.rs4
-rw-r--r--src/test/run-pass/cycle-generic-bound.rs4
-rw-r--r--src/test/run-pass/issue-22356.rs4
-rw-r--r--src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs4
-rw-r--r--src/test/run-pass/traits-conditional-dispatch.rs4
-rw-r--r--src/test/run-pass/unsized.rs20
-rw-r--r--src/test/run-pass/variance-trait-matching.rs49
-rw-r--r--src/test/run-pass/where-for-self.rs7
61 files changed, 332 insertions, 583 deletions
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 7843be0b483..3f85af97197 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -192,13 +192,16 @@ struct TyDesc {
     align: usize
 }
 
+trait AllTypes { fn dummy(&self) { } }
+impl<T:?Sized> AllTypes for T { }
+
 unsafe fn get_tydesc<T>() -> *const TyDesc {
     use std::raw::TraitObject;
 
     let ptr = &*(1 as *const T);
 
     // Can use any trait that is implemented for all types.
-    let obj = mem::transmute::<&marker::MarkerTrait, TraitObject>(ptr);
+    let obj = mem::transmute::<&AllTypes, TraitObject>(ptr);
     obj.vtable as *const TyDesc
 }
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 619f983aee0..352f7d86977 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -35,6 +35,7 @@ use hash::Hasher;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
+#[allow(deprecated)]
 pub unsafe trait Send : MarkerTrait {
     // empty.
 }
@@ -50,6 +51,7 @@ impl !Send for Managed { }
 #[lang="sized"]
 #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
 #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
+#[allow(deprecated)]
 pub trait Sized : MarkerTrait {
     // Empty.
 }
@@ -203,6 +205,7 @@ pub trait Copy : Clone {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
+#[allow(deprecated)]
 pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
@@ -269,84 +272,41 @@ macro_rules! impls{
         )
 }
 
-/// `MarkerTrait` is intended to be used as the supertrait for traits
-/// that don't have any methods but instead serve just to designate
-/// categories of types. An example would be the `Send` trait, which
-/// indicates types that are sendable: `Send` does not itself offer
-/// any methods, but instead is used to gate access to data.
-///
-/// FIXME. Better documentation needed here!
-#[stable(feature = "rust1", since = "1.0.0")]
+/// `MarkerTrait` is deprecated and no longer needed.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "No longer needed")]
+#[allow(deprecated)]
+#[cfg(stage0)]
 pub trait MarkerTrait : PhantomFn<Self,Self> { }
-//                                    ~~~~~ <-- FIXME(#22806)?
-//
-// Marker trait has been made invariant so as to avoid inf recursion,
-// but we should ideally solve the underlying problem. That's a bit
-// complicated.
 
+/// `MarkerTrait` is deprecated and no longer needed.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "No longer needed")]
+#[allow(deprecated)]
+#[cfg(not(stage0))]
+pub trait MarkerTrait { }
+
+#[allow(deprecated)]
 impl<T:?Sized> MarkerTrait for T { }
 
-/// `PhantomFn` is a marker trait for use with traits that contain
-/// type or lifetime parameters that do not appear in any of their
-/// methods. In that case, you can either remove those parameters, or
-/// add a `PhantomFn` supertrait that reflects the signature of
-/// methods that compiler should "pretend" exists. This most commonly
-/// occurs for traits with no methods: in that particular case, you
-/// can extend `MarkerTrait`, which is equivalent to
-/// `PhantomFn<Self>`.
-///
-/// # Examples
-///
-/// As an example, consider a trait with no methods like `Even`, meant
-/// to represent types that are "even":
-///
-/// ```rust,ignore
-/// trait Even { }
-/// ```
-///
-/// In this case, because the implicit parameter `Self` is unused, the
-/// compiler will issue an error. The only purpose of this trait is to
-/// categorize types (and hence instances of those types) as "even" or
-/// not, so if we *were* going to have a method, it might look like:
-///
-/// ```rust,ignore
-/// trait Even {
-///     fn is_even(self) -> bool { true }
-/// }
-/// ```
-///
-/// Therefore, we can model a method like this as follows:
-///
-/// ```
-/// use std::marker::PhantomFn;
-/// trait Even : PhantomFn<Self> { }
-/// ```
-///
-/// Another equivalent, but clearer, option would be to use
-/// `MarkerTrait`:
-///
-/// ```
-/// # #![feature(core)]
-/// use std::marker::MarkerTrait;
-/// trait Even : MarkerTrait { }
-/// ```
-///
-/// # Parameters
-///
-/// - `A` represents the type of the method's argument. You can use a
-///   tuple to represent "multiple" arguments. Any types appearing here
-///   will be considered "contravariant".
-/// - `R`, if supplied, represents the method's return type. This defaults
-///   to `()` as it is rarely needed.
-///
-/// # Additional reading
-///
-/// More details and background can be found in [RFC 738][738].
-///
-/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
+/// `PhantomFn` is a deprecated marker trait that is no longer needed.
 #[lang="phantom_fn"]
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "No longer needed")]
+#[cfg(stage0)]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> {
+}
+
+/// `PhantomFn` is a deprecated marker trait that is no longer needed.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "No longer needed")]
+#[cfg(not(stage0))]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> {
+}
+
+#[allow(deprecated)]
+#[cfg(not(stage0))]
+impl<A:?Sized,R:?Sized,T:?Sized> PhantomFn<A,R> for T { }
 
 /// `PhantomData<T>` allows you to describe that a type acts as if it stores a value of type `T`,
 /// even though it does not. This allows you to inform the compiler about certain safety properties
@@ -444,6 +404,7 @@ mod impls {
 /// [1]: http://en.wikipedia.org/wiki/Parametricity
 #[rustc_reflect_like]
 #[unstable(feature = "core", reason = "requires RFC and more experience")]
+#[allow(deprecated)]
 pub trait Reflect : MarkerTrait {
 }
 
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 230587b726f..3df4d00f60c 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -14,6 +14,7 @@ use marker::{Sized, MarkerTrait};
 use ops::Deref;
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
+#[allow(deprecated)]
 pub unsafe trait Zeroable : MarkerTrait {}
 
 unsafe impl<T:?Sized> Zeroable for *const T {}
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index a08de58f909..89a8625856c 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -321,7 +321,6 @@ lets_do_this! {
     ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
     OwnedBoxLangItem,                "owned_box",               owned_box;
 
-    PhantomFnItem,                   "phantom_fn",              phantom_fn;
     PhantomDataItem,                 "phantom_data",            phantom_data;
 
     // Deprecated:
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
index af6bb4ccccd..a2ff86cd065 100644
--- a/src/librustc/middle/traits/object_safety.rs
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -138,11 +138,10 @@ fn supertraits_reference_self<'tcx>(tcx: &ty::ctxt<'tcx>,
             match predicate {
                 ty::Predicate::Trait(ref data) => {
                     // In the case of a trait predicate, we can skip the "self" type.
-                    Some(data.def_id()) != tcx.lang_items.phantom_fn() &&
-                        data.0.trait_ref.substs.types.get_slice(TypeSpace)
-                                                     .iter()
-                                                     .cloned()
-                                                     .any(is_self)
+                    data.0.trait_ref.substs.types.get_slice(TypeSpace)
+                                                 .iter()
+                                                 .cloned()
+                                                 .any(is_self)
                 }
                 ty::Predicate::Projection(..) |
                 ty::Predicate::TypeOutlives(..) |
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index f7e7d071f8c..ad7d96c652d 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -836,14 +836,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ambiguous: false
         };
 
-        // Check for the `PhantomFn` trait. This is really just a
-        // special annotation that is *always* considered to match, no
-        // matter what the type parameters are etc.
-        if self.tcx().lang_items.phantom_fn() == Some(obligation.predicate.def_id()) {
-            candidates.vec.push(PhantomFnCandidate);
-            return Ok(candidates);
-        }
-
         // Other bounds. Consider both in-scope bounds from fn decl
         // and applicable impls. There is a certain set of precedence rules here.
 
diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs
index 1205b7d9579..3a55a64314e 100644
--- a/src/librustc/middle/ty_relate/mod.rs
+++ b/src/librustc/middle/ty_relate/mod.rs
@@ -122,11 +122,11 @@ fn relate_item_substs<'a,'tcx:'a,R>(relation: &mut R,
     relate_substs(relation, opt_variances, a_subst, b_subst)
 }
 
-fn relate_substs<'a,'tcx,R>(relation: &mut R,
-                            variances: Option<&ty::ItemVariances>,
-                            a_subst: &Substs<'tcx>,
-                            b_subst: &Substs<'tcx>)
-                            -> RelateResult<'tcx, Substs<'tcx>>
+fn relate_substs<'a,'tcx:'a,R>(relation: &mut R,
+                               variances: Option<&ty::ItemVariances>,
+                               a_subst: &Substs<'tcx>,
+                               b_subst: &Substs<'tcx>)
+                               -> RelateResult<'tcx, Substs<'tcx>>
     where R: TypeRelation<'a,'tcx>
 {
     let mut substs = Substs::empty();
@@ -161,11 +161,11 @@ fn relate_substs<'a,'tcx,R>(relation: &mut R,
     Ok(substs)
 }
 
-fn relate_type_params<'a,'tcx,R>(relation: &mut R,
-                                 variances: Option<&[ty::Variance]>,
-                                 a_tys: &[Ty<'tcx>],
-                                 b_tys: &[Ty<'tcx>])
-                                 -> RelateResult<'tcx, Vec<Ty<'tcx>>>
+fn relate_type_params<'a,'tcx:'a,R>(relation: &mut R,
+                                    variances: Option<&[ty::Variance]>,
+                                    a_tys: &[Ty<'tcx>],
+                                    b_tys: &[Ty<'tcx>])
+                                    -> RelateResult<'tcx, Vec<Ty<'tcx>>>
     where R: TypeRelation<'a,'tcx>
 {
     if a_tys.len() != b_tys.len() {
@@ -264,10 +264,10 @@ impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::FnSig<'tcx> {
     }
 }
 
-fn relate_arg_vecs<'a,'tcx,R>(relation: &mut R,
-                              a_args: &[Ty<'tcx>],
-                              b_args: &[Ty<'tcx>])
-                              -> RelateResult<'tcx, Vec<Ty<'tcx>>>
+fn relate_arg_vecs<'a,'tcx:'a,R>(relation: &mut R,
+                                 a_args: &[Ty<'tcx>],
+                                 b_args: &[Ty<'tcx>])
+                                 -> RelateResult<'tcx, Vec<Ty<'tcx>>>
     where R: TypeRelation<'a,'tcx>
 {
     if a_args.len() != b_args.len() {
@@ -629,10 +629,10 @@ impl<'a,'tcx:'a,T> Relate<'a,'tcx> for Box<T>
 ///////////////////////////////////////////////////////////////////////////
 // Error handling
 
-pub fn expected_found<'a,'tcx,R,T>(relation: &mut R,
-                                   a: &T,
-                                   b: &T)
-                                   -> ty::expected_found<T>
+pub fn expected_found<'a,'tcx:'a,R,T>(relation: &mut R,
+                                      a: &T,
+                                      b: &T)
+                                      -> ty::expected_found<T>
     where R: TypeRelation<'a,'tcx>, T: Clone
 {
     expected_found_bool(relation.a_is_expected(), a, b)
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index a86e2b17c93..eb06caf7d5a 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -117,15 +117,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
 
                 self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemTrait(_, ref ast_generics, _, ref items) => {
+            ast::ItemTrait(_, _, _, ref items) => {
                 let trait_predicates =
                     ty::lookup_predicates(ccx.tcx, local_def(item.id));
-                reject_non_type_param_bounds(
-                    ccx.tcx,
-                    item.span,
-                    &trait_predicates);
-                self.check_variances(item, ast_generics, &trait_predicates,
-                                     self.tcx().lang_items.phantom_fn());
+                reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates);
                 if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) {
                     if !items.is_empty() {
                         ccx.tcx.sess.span_err(
@@ -287,30 +282,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                                      ast_generics: &ast::Generics)
     {
         let item_def_id = local_def(item.id);
-        let predicates = ty::lookup_predicates(self.tcx(), item_def_id);
-        self.check_variances(item,
-                             ast_generics,
-                             &predicates,
-                             self.tcx().lang_items.phantom_data());
-    }
-
-    fn check_variances(&self,
-                       item: &ast::Item,
-                       ast_generics: &ast::Generics,
-                       ty_predicates: &ty::GenericPredicates<'tcx>,
-                       suggested_marker_id: Option<ast::DefId>)
-    {
-        let variance_lang_items = &[
-            self.tcx().lang_items.phantom_fn(),
-            self.tcx().lang_items.phantom_data(),
-        ];
-
-        let item_def_id = local_def(item.id);
-        let is_lang_item = variance_lang_items.iter().any(|n| *n == Some(item_def_id));
-        if is_lang_item {
-            return;
-        }
-
+        let ty_predicates = ty::lookup_predicates(self.tcx(), item_def_id);
         let variances = ty::item_variances(self.tcx(), item_def_id);
 
         let mut constrained_parameters: HashSet<_> =
@@ -331,7 +303,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                 continue;
             }
             let span = self.ty_param_span(ast_generics, item, space, index);
-            self.report_bivariance(span, param_ty.name, suggested_marker_id);
+            self.report_bivariance(span, param_ty.name);
         }
 
         for (space, index, &variance) in variances.regions.iter_enumerated() {
@@ -342,7 +314,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             assert_eq!(space, TypeSpace);
             let span = ast_generics.lifetimes[index].lifetime.span;
             let name = ast_generics.lifetimes[index].lifetime.name;
-            self.report_bivariance(span, name, suggested_marker_id);
+            self.report_bivariance(span, name);
         }
     }
 
@@ -377,14 +349,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
 
     fn report_bivariance(&self,
                          span: Span,
-                         param_name: ast::Name,
-                         suggested_marker_id: Option<ast::DefId>)
+                         param_name: ast::Name)
     {
         self.tcx().sess.span_err(
             span,
             &format!("parameter `{}` is never used",
                      param_name.user_string(self.tcx())));
 
+        let suggested_marker_id = self.tcx().lang_items.phantom_data();
         match suggested_marker_id {
             Some(def_id) => {
                 self.tcx().sess.fileline_help(
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index b83d8fc6af7..da2de731d64 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -18,34 +18,121 @@
 //! defined on type `X`, we only consider the definition of the type `X`
 //! and the definitions of any types it references.
 //!
-//! We only infer variance for type parameters found on *types*: structs,
-//! enums, and traits. We do not infer variance for type parameters found
-//! on fns or impls. This is because those things are not type definitions
-//! and variance doesn't really make sense in that context.
-//!
-//! It is worth covering what variance means in each case. For structs and
-//! enums, I think it is fairly straightforward. The variance of the type
+//! We only infer variance for type parameters found on *data types*
+//! like structs and enums. In these cases, there is fairly straightforward
+//! explanation for what variance means. The variance of the type
 //! or lifetime parameters defines whether `T<A>` is a subtype of `T<B>`
 //! (resp. `T<'a>` and `T<'b>`) based on the relationship of `A` and `B`
-//! (resp. `'a` and `'b`). (FIXME #3598 -- we do not currently make use of
-//! the variances we compute for type parameters.)
+//! (resp. `'a` and `'b`).
+//!
+//! We do not infer variance for type parameters found on traits, fns,
+//! or impls. Variance on trait parameters can make indeed make sense
+//! (and we used to compute it) but it is actually rather subtle in
+//! meaning and not that useful in practice, so we removed it. See the
+//! addendum for some details. Variances on fn/impl parameters, otoh,
+//! doesn't make sense because these parameters are instantiated and
+//! then forgotten, they don't persist in types or compiled
+//! byproducts.
+//!
+//! ### The algorithm
+//!
+//! The basic idea is quite straightforward. We iterate over the types
+//! defined and, for each use of a type parameter X, accumulate a
+//! constraint indicating that the variance of X must be valid for the
+//! variance of that use site. We then iteratively refine the variance of
+//! X until all constraints are met. There is *always* a sol'n, because at
+//! the limit we can declare all type parameters to be invariant and all
+//! constraints will be satisfied.
+//!
+//! As a simple example, consider:
+//!
+//!     enum Option<A> { Some(A), None }
+//!     enum OptionalFn<B> { Some(|B|), None }
+//!     enum OptionalMap<C> { Some(|C| -> C), None }
+//!
+//! Here, we will generate the constraints:
+//!
+//!     1. V(A) <= +
+//!     2. V(B) <= -
+//!     3. V(C) <= +
+//!     4. V(C) <= -
+//!
+//! These indicate that (1) the variance of A must be at most covariant;
+//! (2) the variance of B must be at most contravariant; and (3, 4) the
+//! variance of C must be at most covariant *and* contravariant. All of these
+//! results are based on a variance lattice defined as follows:
+//!
+//!       *      Top (bivariant)
+//!    -     +
+//!       o      Bottom (invariant)
+//!
+//! Based on this lattice, the solution V(A)=+, V(B)=-, V(C)=o is the
+//! optimal solution. Note that there is always a naive solution which
+//! just declares all variables to be invariant.
+//!
+//! You may be wondering why fixed-point iteration is required. The reason
+//! is that the variance of a use site may itself be a function of the
+//! variance of other type parameters. In full generality, our constraints
+//! take the form:
+//!
+//!     V(X) <= Term
+//!     Term := + | - | * | o | V(X) | Term x Term
+//!
+//! Here the notation V(X) indicates the variance of a type/region
+//! parameter `X` with respect to its defining class. `Term x Term`
+//! represents the "variance transform" as defined in the paper:
+//!
+//!   If the variance of a type variable `X` in type expression `E` is `V2`
+//!   and the definition-site variance of the [corresponding] type parameter
+//!   of a class `C` is `V1`, then the variance of `X` in the type expression
+//!   `C<E>` is `V3 = V1.xform(V2)`.
+//!
+//! ### Constraints
+//!
+//! If I have a struct or enum with where clauses:
+//!
+//!     struct Foo<T:Bar> { ... }
+//!
+//! you might wonder whether the variance of `T` with respect to `Bar`
+//! affects the variance `T` with respect to `Foo`. I claim no.  The
+//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t
+//! `Foo`. And then we have a `Foo<X>` that is upcast to `Foo<Y>`, where
+//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold.  In that
+//! case, the upcast will be illegal, but not because of a variance
+//! failure, but rather because the target type `Foo<Y>` is itself just
+//! not well-formed. Basically we get to assume well-formedness of all
+//! types involved before considering variance.
+//!
+//! ### Addendum: Variance on traits
 //!
-//! ### Variance on traits
+//! As mentioned above, we used to permit variance on traits. This was
+//! computed based on the appearance of trait type parameters in
+//! method signatures and was used to represent the compatibility of
+//! vtables in trait objects (and also "virtual" vtables or dictionary
+//! in trait bounds). One complication was that variance for
+//! associated types is less obvious, since they can be projected out
+//! and put to myriad uses, so it's not clear when it is safe to allow
+//! `X<A>::Bar` to vary (or indeed just what that means). Moreover (as
+//! covered below) all inputs on any trait with an associated type had
+//! to be invariant, limiting the applicability. Finally, the
+//! annotations (`MarkerTrait`, `PhantomFn`) needed to ensure that all
+//! trait type parameters had a variance were confusing and annoying
+//! for little benefit.
 //!
-//! The meaning of variance for trait parameters is more subtle and worth
-//! expanding upon. There are in fact two uses of the variance values we
-//! compute.
+//! Just for historical reference,I am going to preserve some text indicating
+//! how one could interpret variance and trait matching.
 //!
-//! #### Trait variance and object types
+//! #### Variance and object types
 //!
-//! The first is for object types. Just as with structs and enums, we can
-//! decide the subtyping relationship between two object types `&Trait<A>`
-//! and `&Trait<B>` based on the relationship of `A` and `B`. Note that
-//! for object types we ignore the `Self` type parameter -- it is unknown,
-//! and the nature of dynamic dispatch ensures that we will always call a
+//! Just as with structs and enums, we can decide the subtyping
+//! relationship between two object types `&Trait<A>` and `&Trait<B>`
+//! based on the relationship of `A` and `B`. Note that for object
+//! types we ignore the `Self` type parameter -- it is unknown, and
+//! the nature of dynamic dispatch ensures that we will always call a
 //! function that is expected the appropriate `Self` type. However, we
-//! must be careful with the other type parameters, or else we could end
-//! up calling a function that is expecting one type but provided another.
+//! must be careful with the other type parameters, or else we could
+//! end up calling a function that is expecting one type but provided
+//! another.
 //!
 //! To see what I mean, consider a trait like so:
 //!
@@ -135,104 +222,24 @@
 //!
 //! These conditions are satisfied and so we are happy.
 //!
-//! ### The algorithm
+//! #### Variance and associated types
 //!
-//! The basic idea is quite straightforward. We iterate over the types
-//! defined and, for each use of a type parameter X, accumulate a
-//! constraint indicating that the variance of X must be valid for the
-//! variance of that use site. We then iteratively refine the variance of
-//! X until all constraints are met. There is *always* a sol'n, because at
-//! the limit we can declare all type parameters to be invariant and all
-//! constraints will be satisfied.
-//!
-//! As a simple example, consider:
-//!
-//!     enum Option<A> { Some(A), None }
-//!     enum OptionalFn<B> { Some(|B|), None }
-//!     enum OptionalMap<C> { Some(|C| -> C), None }
-//!
-//! Here, we will generate the constraints:
-//!
-//!     1. V(A) <= +
-//!     2. V(B) <= -
-//!     3. V(C) <= +
-//!     4. V(C) <= -
-//!
-//! These indicate that (1) the variance of A must be at most covariant;
-//! (2) the variance of B must be at most contravariant; and (3, 4) the
-//! variance of C must be at most covariant *and* contravariant. All of these
-//! results are based on a variance lattice defined as follows:
-//!
-//!       *      Top (bivariant)
-//!    -     +
-//!       o      Bottom (invariant)
-//!
-//! Based on this lattice, the solution V(A)=+, V(B)=-, V(C)=o is the
-//! optimal solution. Note that there is always a naive solution which
-//! just declares all variables to be invariant.
-//!
-//! You may be wondering why fixed-point iteration is required. The reason
-//! is that the variance of a use site may itself be a function of the
-//! variance of other type parameters. In full generality, our constraints
-//! take the form:
-//!
-//!     V(X) <= Term
-//!     Term := + | - | * | o | V(X) | Term x Term
-//!
-//! Here the notation V(X) indicates the variance of a type/region
-//! parameter `X` with respect to its defining class. `Term x Term`
-//! represents the "variance transform" as defined in the paper:
-//!
-//!   If the variance of a type variable `X` in type expression `E` is `V2`
-//!   and the definition-site variance of the [corresponding] type parameter
-//!   of a class `C` is `V1`, then the variance of `X` in the type expression
-//!   `C<E>` is `V3 = V1.xform(V2)`.
-//!
-//! ### Constraints
-//!
-//! If I have a struct or enum with where clauses:
-//!
-//!     struct Foo<T:Bar> { ... }
-//!
-//! you might wonder whether the variance of `T` with respect to `Bar`
-//! affects the variance `T` with respect to `Foo`. I claim no.  The
-//! reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t
-//! `Foo`. And then we have a `Foo<X>` that is upcast to `Foo<Y>`, where
-//! `X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold.  In that
-//! case, the upcast will be illegal, but not because of a variance
-//! failure, but rather because the target type `Foo<Y>` is itself just
-//! not well-formed. Basically we get to assume well-formedness of all
-//! types involved before considering variance.
-//!
-//! ### Associated types
-//!
-//! Any trait with an associated type is invariant with respect to all
-//! of its inputs. To see why this makes sense, consider what
-//! subtyping for a trait reference means:
+//! Traits with associated types -- or at minimum projection
+//! expressions -- must be invariant with respect to all of their
+//! inputs. To see why this makes sense, consider what subtyping for a
+//! trait reference means:
 //!
 //!    <T as Trait> <: <U as Trait>
 //!
-//! means that if I know that `T as Trait`,
-//! I also know that `U as
-//! Trait`. Moreover, if you think of it as
-//! dictionary passing style, it means that
-//! a dictionary for `<T as Trait>` is safe
-//! to use where a dictionary for `<U as
-//! Trait>` is expected.
-//!
-//! The problem is that when you can
-//! project types out from `<T as Trait>`,
-//! the relationship to types projected out
-//! of `<U as Trait>` is completely unknown
-//! unless `T==U` (see #21726 for more
-//! details). Making `Trait` invariant
-//! ensures that this is true.
+//! means that if I know that `T as Trait`, I also know that `U as
+//! Trait`. Moreover, if you think of it as dictionary passing style,
+//! it means that a dictionary for `<T as Trait>` is safe to use where
+//! a dictionary for `<U as Trait>` is expected.
 //!
-//! *Historical note: we used to preserve this invariant another way,
-//! by tweaking the subtyping rules and requiring that when a type `T`
-//! appeared as part of a projection, that was considered an invariant
-//! location, but this version does away with the need for those
-//! somewhat "special-case-feeling" rules.*
+//! The problem is that when you can project types out from `<T as
+//! Trait>`, the relationship to types projected out of `<U as Trait>`
+//! is completely unknown unless `T==U` (see #21726 for more
+//! details). Making `Trait` invariant ensures that this is true.
 //!
 //! Another related reason is that if we didn't make traits with
 //! associated types invariant, then projection is no longer a
@@ -383,7 +390,6 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
 
 fn lang_items(tcx: &ty::ctxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
     let all = vec![
-        (tcx.lang_items.phantom_fn(), vec![ty::Contravariant, ty::Covariant]),
         (tcx.lang_items.phantom_data(), vec![ty::Covariant]),
         (tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
 
@@ -520,6 +526,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
                 self.add_inferreds_for_item(item.id, false, generics);
             }
             ast::ItemTrait(_, ref generics, _, _) => {
+                // Note: all inputs for traits are ultimately
+                // constrained to be invariant. See `visit_item` in
+                // the impl for `ConstraintContext` below.
                 self.add_inferreds_for_item(item.id, true, generics);
                 visit::walk_item(self, item);
             }
@@ -644,39 +653,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
 
             ast::ItemTrait(..) => {
                 let trait_def = ty::lookup_trait_def(tcx, did);
-                let predicates = ty::lookup_super_predicates(tcx, did);
-                self.add_constraints_from_predicates(&trait_def.generics,
-                                                     predicates.predicates.as_slice(),
-                                                     self.covariant);
-
-                let trait_items = ty::trait_items(tcx, did);
-                for trait_item in &*trait_items {
-                    match *trait_item {
-                        ty::MethodTraitItem(ref method) => {
-                            self.add_constraints_from_predicates(
-                                &method.generics,
-                                method.predicates.predicates.get_slice(FnSpace),
-                                self.contravariant);
-
-                            self.add_constraints_from_sig(
-                                &method.generics,
-                                &method.fty.sig,
-                                self.covariant);
-                        }
-                        ty::TypeTraitItem(ref data) => {
-                            // Any trait with an associated type is
-                            // invariant with respect to all of its
-                            // inputs. See length discussion in the comment
-                            // on this module.
-                            let projection_ty = ty::mk_projection(tcx,
-                                                                  trait_def.trait_ref.clone(),
-                                                                  data.name);
-                            self.add_constraints_from_ty(&trait_def.generics,
-                                                         projection_ty,
-                                                         self.invariant);
-                        }
-                    }
-                }
+                self.add_constraints_from_trait_ref(&trait_def.generics,
+                                                    &trait_def.trait_ref,
+                                                    self.invariant);
             }
 
             ast::ItemExternCrate(_) |
@@ -1045,69 +1024,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         }
     }
 
-    fn add_constraints_from_predicates(&mut self,
-                                       generics: &ty::Generics<'tcx>,
-                                       predicates: &[ty::Predicate<'tcx>],
-                                       variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_generics({})",
-               generics.repr(self.tcx()));
-
-        for predicate in predicates.iter() {
-            match *predicate {
-                ty::Predicate::Trait(ty::Binder(ref data)) => {
-                    self.add_constraints_from_trait_ref(generics, &*data.trait_ref, variance);
-                }
-
-                ty::Predicate::Equate(ty::Binder(ref data)) => {
-                    // A == B is only true if A and B are the same
-                    // types, not subtypes of one another, so this is
-                    // an invariant position:
-                    self.add_constraints_from_ty(generics, data.0, self.invariant);
-                    self.add_constraints_from_ty(generics, data.1, self.invariant);
-                }
-
-                ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
-                    // Why contravariant on both? Let's consider:
-                    //
-                    // Under what conditions is `(T:'t) <: (U:'u)`,
-                    // meaning that `(T:'t) => (U:'u)`. The answer is
-                    // if `U <: T` or `'u <= 't`. Let's see some examples:
-                    //
-                    //   (T: 'big) => (T: 'small)
-                    //   where 'small <= 'big
-                    //
-                    //   (&'small Foo: 't) => (&'big Foo: 't)
-                    //   where 'small <= 'big
-                    //   note that &'big Foo <: &'small Foo
-
-                    let variance_r = self.xform(variance, self.contravariant);
-                    self.add_constraints_from_ty(generics, data.0, variance_r);
-                    self.add_constraints_from_region(generics, data.1, variance_r);
-                }
-
-                ty::Predicate::RegionOutlives(ty::Binder(ref data)) => {
-                    // `'a : 'b` is still true if 'a gets bigger
-                    self.add_constraints_from_region(generics, data.0, variance);
-
-                    // `'a : 'b` is still true if 'b gets smaller
-                    let variance_r = self.xform(variance, self.contravariant);
-                    self.add_constraints_from_region(generics, data.1, variance_r);
-                }
-
-                ty::Predicate::Projection(ty::Binder(ref data)) => {
-                    self.add_constraints_from_trait_ref(generics,
-                                                        &*data.projection_ty.trait_ref,
-                                                        variance);
-
-                    // as the equality predicate above, a binder is a
-                    // type equality relation, not a subtyping
-                    // relation
-                    self.add_constraints_from_ty(generics, data.ty, self.invariant);
-                }
-            }
-        }
-    }
-
     /// Adds constraints appropriate for a function with signature
     /// `sig` appearing in a context with ambient variance `variance`
     fn add_constraints_from_sig(&mut self,
diff --git a/src/test/auxiliary/coherence_copy_like_lib.rs b/src/test/auxiliary/coherence_copy_like_lib.rs
index a1e1b48c2c4..d3d389c6a8b 100644
--- a/src/test/auxiliary/coherence_copy_like_lib.rs
+++ b/src/test/auxiliary/coherence_copy_like_lib.rs
@@ -11,9 +11,7 @@
 #![crate_type = "rlib"]
 #![feature(fundamental)]
 
-use std::marker::MarkerTrait;
-
-pub trait MyCopy : MarkerTrait { }
+pub trait MyCopy { }
 impl MyCopy for i32 { }
 
 pub struct MyStruct<T>(T);
diff --git a/src/test/auxiliary/coherence_orphan_lib.rs b/src/test/auxiliary/coherence_orphan_lib.rs
index 93d8fd3da88..b22d12300c7 100644
--- a/src/test/auxiliary/coherence_orphan_lib.rs
+++ b/src/test/auxiliary/coherence_orphan_lib.rs
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait TheTrait<T> : ::std::marker::PhantomFn<T> {
+pub trait TheTrait<T> {
     fn the_fn(&self);
 }
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs
index 72dfc75f41b..d195bd7e77b 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/auxiliary/lang-item-public.rs
@@ -12,12 +12,8 @@
 #![no_std]
 #![feature(lang_items)]
 
-#[lang="phantom_fn"]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
 #[lang="sized"]
-pub trait Sized : PhantomFn<Self> {}
+pub trait Sized { }
 
 #[lang="panic"]
 fn panic(_: &(&'static str, &'static str, usize)) -> ! { loop {} }
@@ -29,7 +25,7 @@ extern fn stack_exhausted() {}
 extern fn eh_personality() {}
 
 #[lang="copy"]
-pub trait Copy : PhantomFn<Self> {
+pub trait Copy {
     // Empty.
 }
 
diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
index 04170779ed2..0e083e47236 100644
--- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
+++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
@@ -16,12 +16,8 @@
 #![feature(no_std)]
 #![no_std]
 
-#[lang="phantom_fn"]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
 #[lang="sized"]
-pub trait Sized : PhantomFn<Self> {
+pub trait Sized {
     // Empty.
 }
 
diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs
index f13175ce8e2..fcd6e5c4952 100644
--- a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs
+++ b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct.rs
@@ -18,11 +18,9 @@
 
 extern crate coherence_copy_like_lib as lib;
 
-use std::marker::MarkerTrait;
-
 struct MyType { x: i32 }
 
-trait MyTrait : MarkerTrait { }
+trait MyTrait { }
 impl<T: lib::MyCopy> MyTrait for T { }
 
 // `MyFundamentalStruct` is declared fundamental, so we can test that
diff --git a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs
index ae3d242af70..b5c0a7fb5f5 100644
--- a/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs
+++ b/src/test/compile-fail/coherence_copy_like_err_fundamental_struct_ref.rs
@@ -18,11 +18,9 @@
 
 extern crate coherence_copy_like_lib as lib;
 
-use std::marker::MarkerTrait;
-
 struct MyType { x: i32 }
 
-trait MyTrait : MarkerTrait { }
+trait MyTrait { }
 impl<T: lib::MyCopy> MyTrait for T { }
 
 // `MyFundamentalStruct` is declared fundamental, so we can test that
diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs
index dc697e4784f..ea0d880f4a1 100644
--- a/src/test/compile-fail/issue-13853-2.rs
+++ b/src/test/compile-fail/issue-13853-2.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::marker::PhantomFn;
-
-trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { }
+trait FromStructReader<'a> { }
 trait ResponseHook {
      fn get<'a, T: FromStructReader<'a>>(&'a self);
 }
diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs
index 4435ee0cb22..a4a8eac682d 100644
--- a/src/test/compile-fail/issue-19660.rs
+++ b/src/test/compile-fail/issue-19660.rs
@@ -13,12 +13,8 @@
 #![feature(lang_items, start, no_std)]
 #![no_std]
 
-#[lang="phantom_fn"]
-trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
 #[lang = "sized"]
-trait Sized : PhantomFn<Self> {}
+trait Sized { }
 
 #[start]
 fn main(_: isize, _: *const *const u8) -> isize {
diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs
index 71494fd5f38..d4ee93e9ca5 100644
--- a/src/test/compile-fail/kindck-impl-type-params.rs
+++ b/src/test/compile-fail/kindck-impl-type-params.rs
@@ -41,7 +41,7 @@ fn g<T>(val: T) {
 fn foo<'a>() {
     let t: S<&'a isize> = S(marker::PhantomData);
     let a = &t as &Gettable<&'a isize>;
-    //~^ ERROR cannot infer
+    //~^ ERROR does not fulfill
 }
 
 fn foo2<'a>() {
diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs
index 8440cf3a88e..10f245aaaf9 100644
--- a/src/test/compile-fail/lint-unsafe-code.rs
+++ b/src/test/compile-fail/lint-unsafe-code.rs
@@ -12,18 +12,15 @@
 #![allow(dead_code)]
 #![deny(unsafe_code)]
 
-use std::marker::PhantomFn;
-
 struct Bar;
 struct Bar2;
 struct Bar3;
 
 #[allow(unsafe_code)]
 mod allowed_unsafe {
-    use std::marker::PhantomFn;
     fn allowed() { unsafe {} }
     unsafe fn also_allowed() {}
-    unsafe trait AllowedUnsafe : PhantomFn<Self> {}
+    unsafe trait AllowedUnsafe { }
     unsafe impl AllowedUnsafe for super::Bar {}
 }
 
@@ -34,7 +31,7 @@ macro_rules! unsafe_in_macro {
 }
 
 unsafe fn baz() {} //~ ERROR: declaration of an `unsafe` function
-unsafe trait Foo : PhantomFn<Self> {} //~ ERROR: declaration of an `unsafe` trait
+unsafe trait Foo {} //~ ERROR: declaration of an `unsafe` trait
 unsafe impl Foo for Bar {} //~ ERROR: implementation of an `unsafe` trait
 
 trait Baz {
diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs
index 1c95ee43d27..518c45ac9df 100644
--- a/src/test/compile-fail/object-safety-phantom-fn.rs
+++ b/src/test/compile-fail/object-safety-phantom-fn.rs
@@ -13,12 +13,10 @@
 #![feature(rustc_attrs)]
 #![allow(dead_code)]
 
-use std::marker::PhantomFn;
-
-trait Baz : PhantomFn<Self> {
+trait Baz {
 }
 
-trait Bar<T> : PhantomFn<(Self, T)> {
+trait Bar<T> {
 }
 
 fn make_bar<T:Bar<u32>>(t: &T) -> &Bar<u32> {
diff --git a/src/test/compile-fail/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs
index 7538b1c85e5..8580749084d 100644
--- a/src/test/compile-fail/on-unimplemented-bad-anno.rs
+++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs
@@ -13,11 +13,8 @@
 
 #![allow(unused)]
 
-use std::marker;
-
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
 trait Foo<Bar, Baz, Quux>
-    : marker::PhantomFn<(Self,Bar,Baz,Quux)>
 {}
 
 #[rustc_on_unimplemented="a collection of type `{Self}` cannot be built from an iterator over elements of type `{A}`"]
@@ -28,19 +25,16 @@ trait MyFromIterator<A> {
 
 #[rustc_on_unimplemented] //~ ERROR this attribute must have a value
 trait BadAnnotation1
-    : marker::MarkerTrait
 {}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
 //~^ ERROR there is no type parameter C on trait BadAnnotation2
 trait BadAnnotation2<A,B>
-    : marker::PhantomFn<(Self,A,B)>
 {}
 
 #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
 //~^ only named substitution parameters are allowed
 trait BadAnnotation3<A,B>
-    : marker::PhantomFn<(Self,A,B)>
 {}
 
 pub fn main() {
diff --git a/src/test/compile-fail/on-unimplemented.rs b/src/test/compile-fail/on-unimplemented.rs
index 2447d086422..c4eb467c4f9 100644
--- a/src/test/compile-fail/on-unimplemented.rs
+++ b/src/test/compile-fail/on-unimplemented.rs
@@ -11,11 +11,8 @@
 
 #![feature(on_unimplemented)]
 
-use std::marker;
-
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
 trait Foo<Bar, Baz, Quux>
-    : marker::PhantomFn<(Self,Bar,Baz,Quux)>
 {}
 
 fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index 67dccb4c93e..f728fdfaf9a 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -11,15 +11,11 @@
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
-#[lang="phantom_fn"]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
 #[lang="sized"]
-pub trait Sized : PhantomFn<Self> {}
+pub trait Sized {}
 
 #[lang="copy"]
-pub trait Copy : PhantomFn<Self> {}
+pub trait Copy {}
 
 mod bar {
     // shouldn't bring in too much
diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs
index adce93af079..bcb46663aa8 100644
--- a/src/test/compile-fail/privacy4.rs
+++ b/src/test/compile-fail/privacy4.rs
@@ -11,12 +11,8 @@
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
-#[lang="phantom_fn"]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
-#[lang = "sized"] pub trait Sized : PhantomFn<Self> {}
-#[lang="copy"] pub trait Copy : PhantomFn<Self> {}
+#[lang = "sized"] pub trait Sized {}
+#[lang="copy"] pub trait Copy {}
 
 // Test to make sure that private items imported through globs remain private
 // when  they're used.
diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
index 6aa0cc003ce..9a13541bd0b 100644
--- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
+++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs
@@ -15,11 +15,9 @@
 
 #![allow(dead_code)]
 
-use std::marker::PhantomFn;
-
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait: PhantomFn<Self, Self> {
+pub trait TheTrait {
     type TheAssocType;
 }
 
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
index 9736910d7b5..0d3d2e296be 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container-hrtb.rs
@@ -14,11 +14,9 @@
 #![allow(dead_code)]
 #![feature(rustc_attrs)]
 
-use std::marker::PhantomFn;
-
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait<'b> : PhantomFn<&'b Self,Self> {
+pub trait TheTrait<'b> {
     type TheAssocType;
 }
 
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
index da7546ce21c..2ceaea98d27 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs
@@ -15,11 +15,9 @@
 
 #![allow(dead_code)]
 
-use std::marker::PhantomFn;
-
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait: PhantomFn<Self, Self> {
+pub trait TheTrait {
     type TheAssocType;
 }
 
diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
index e1e72e6f56e..e3e57ff1711 100644
--- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs
+++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs
@@ -15,11 +15,9 @@
 #![allow(dead_code)]
 #![feature(rustc_attrs)]
 
-use std::marker::PhantomFn;
-
 ///////////////////////////////////////////////////////////////////////////
 
-pub trait TheTrait: PhantomFn<Self, Self> {
+pub trait TheTrait {
     type TheAssocType;
 }
 
diff --git a/src/test/compile-fail/regions-close-object-into-object-1.rs b/src/test/compile-fail/regions-close-object-into-object-1.rs
index 4c831a2b659..5472e09ba4b 100644
--- a/src/test/compile-fail/regions-close-object-into-object-1.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-1.rs
@@ -11,12 +11,10 @@
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-use std::marker::PhantomFn;
-
-trait A<T> : PhantomFn<(Self,T)> { }
+trait A<T> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X : ::std::marker::MarkerTrait {}
+trait X { }
 
 impl<'a, T> X for B<'a, T> {}
 
diff --git a/src/test/compile-fail/regions-close-object-into-object-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs
index 6de49020a6f..1ef000852d5 100644
--- a/src/test/compile-fail/regions-close-object-into-object-2.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-2.rs
@@ -10,12 +10,10 @@
 
 #![feature(box_syntax)]
 
-use std::marker::PhantomFn;
-
-trait A<T> : PhantomFn<(Self,T)> { }
+trait A<T> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X : PhantomFn<Self> {}
+trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn g<'a, T: 'static>(v: Box<A<T>+'a>) -> Box<X+'static> {
diff --git a/src/test/compile-fail/regions-close-object-into-object-3.rs b/src/test/compile-fail/regions-close-object-into-object-3.rs
index b723efff3c9..b7dc759b271 100644
--- a/src/test/compile-fail/regions-close-object-into-object-3.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-3.rs
@@ -11,15 +11,13 @@
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-use std::marker::PhantomFn;
-
-trait A<T> : PhantomFn<(Self,T)> {}
+trait A<T> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X : PhantomFn<Self> {}
+trait X { }
 impl<'a, T> X for B<'a, T> {}
 
-fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
+fn h<'a, T, U:'static>(v: Box<A<U>+'static>) -> Box<X+'static> {
     box B(&*v) as Box<X> //~ ERROR `*v` does not live long enough
 }
 
diff --git a/src/test/compile-fail/regions-close-object-into-object-4.rs b/src/test/compile-fail/regions-close-object-into-object-4.rs
index 9b311588bb1..247578d253e 100644
--- a/src/test/compile-fail/regions-close-object-into-object-4.rs
+++ b/src/test/compile-fail/regions-close-object-into-object-4.rs
@@ -10,12 +10,10 @@
 
 #![feature(box_syntax)]
 
-use std::marker::PhantomFn;
-
-trait A<T> : PhantomFn<(Self,T)> {}
+trait A<T> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X : PhantomFn<Self> {}
+trait X { }
 impl<'a, T> X for B<'a, T> {}
 
 fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs
index 1b749faf1b8..bb80c763a8b 100644
--- a/src/test/compile-fail/required-lang-item.rs
+++ b/src/test/compile-fail/required-lang-item.rs
@@ -11,11 +11,7 @@
 #![feature(lang_items, no_std)]
 #![no_std]
 
-#[lang="phantom_fn"]
-pub trait PhantomFn<T:?Sized> { }
-impl<T:?Sized, U:?Sized> PhantomFn<T> for U { }
-
-#[lang="sized"] pub trait Sized : PhantomFn<Self> {}
+#[lang="sized"] pub trait Sized { }
 
 // error-pattern:requires `start` lang_item
 
diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
index 34e06cc9365..a2369f8ffb4 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
@@ -13,8 +13,7 @@
 
 use std::marker;
 
-trait A : marker::PhantomFn<Self> {
-}
+trait A { }
 
 trait B: A {}
 
diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
index 217540415a7..beabdcea2bb 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
@@ -15,7 +15,6 @@ trait Iterator<A> {
 }
 
 trait IteratorUtil<A>
-    : ::std::marker::PhantomFn<(),A>
 {
     fn zip<B, U: Iterator<U>>(self, other: U) -> ZipIterator<Self, U>;
 }
diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
index 6d315c1b7a9..dc5576aee65 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
@@ -16,14 +16,12 @@
 #![feature(unboxed_closures)]
 #![allow(dead_code)]
 
-use std::marker::PhantomFn;
-
 trait Foo<T> {
     type Output;
     fn dummy(&self, t: T, u: Self::Output);
 }
 
-trait Eq<X: ?Sized> : PhantomFn<(Self,X)> { }
+trait Eq<X: ?Sized> { }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
diff --git a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
index bd3530e6e30..a6f59b78823 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
@@ -23,7 +23,7 @@ trait Foo<T> {
     fn dummy(&self, t: T);
 }
 
-trait Eq<X: ?Sized> : marker::PhantomFn<(Self, X)> { }
+trait Eq<X: ?Sized> { }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs
index 3330e1d0d51..1795ac95358 100644
--- a/src/test/compile-fail/variance-contravariant-arg-object.rs
+++ b/src/test/compile-fail/variance-contravariant-arg-object.rs
@@ -10,6 +10,9 @@
 
 #![allow(dead_code)]
 
+// Test that even when `T` is only used in contravariant position, it
+// is treated as invariant.
+
 trait Get<T> : 'static {
     fn get(&self, t: T);
 }
@@ -25,7 +28,8 @@ fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
                                    -> Box<Get<&'max i32>>
     where 'max : 'min
 {
-    v
+    // Previously OK:
+    v //~ ERROR mismatched types
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
index caaad4014ad..9b6e3c9de3b 100644
--- a/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
+++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
@@ -10,6 +10,9 @@
 
 #![allow(dead_code)]
 
+// Test that even when `T` is only used in contravariant position, it
+// is treated as invariant.
+
 trait Get<T> {
     fn get(&self, t: T);
 }
@@ -23,7 +26,9 @@ fn get_min_from_max<'min, 'max, G>()
 fn get_max_from_min<'min, 'max, G>()
     where 'max : 'min, G : Get<&'min i32>
 {
-    impls_get::<G,&'max i32>()
+    // Previously OK, but now an error because traits are invariant:
+
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
 }
 
 fn impls_get<G,T>() where G : Get<T> { }
diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
index 013511ed517..6d9d1e61fed 100644
--- a/src/test/compile-fail/variance-contravariant-self-trait-match.rs
+++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
@@ -10,6 +10,9 @@
 
 #![allow(dead_code)]
 
+// Test that even when `Self` is only used in contravariant position, it
+// is treated as invariant.
+
 trait Get {
     fn get(&self);
 }
@@ -23,7 +26,10 @@ fn get_min_from_max<'min, 'max, G>()
 fn get_max_from_min<'min, 'max, G>()
     where 'max : 'min, G : 'max, &'min G : Get
 {
-    impls_get::<&'max G>();
+    // Previously OK, but now error because traits are invariant with
+    // respect to all inputs.
+
+    impls_get::<&'max G>(); //~ ERROR mismatched types
 }
 
 fn impls_get<G>() where G : Get { }
diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs
index 828c987c082..ad059a467f5 100644
--- a/src/test/compile-fail/variance-covariant-arg-object.rs
+++ b/src/test/compile-fail/variance-covariant-arg-object.rs
@@ -10,6 +10,9 @@
 
 #![allow(dead_code)]
 
+// Test that even when `T` is only used in covariant position, it
+// is treated as invariant.
+
 trait Get<T> : 'static {
     fn get(&self) -> T;
 }
@@ -18,7 +21,8 @@ fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
                                 -> Box<Get<&'min i32>>
     where 'max : 'min
 {
-    v
+    // Previously OK, now an error as traits are invariant.
+    v //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
index 17761b9c0b1..c42a845b3b5 100644
--- a/src/test/compile-fail/variance-covariant-arg-trait-match.rs
+++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
@@ -10,6 +10,9 @@
 
 #![allow(dead_code)]
 
+// Test that even when `T` is only used in covariant position, it
+// is treated as invariant.
+
 trait Get<T> {
     fn get(&self) -> T;
 }
@@ -17,7 +20,8 @@ trait Get<T> {
 fn get_min_from_max<'min, 'max, G>()
     where 'max : 'min, G : Get<&'max i32>
 {
-    impls_get::<G,&'min i32>()
+    // Previously OK, now an error as traits are invariant.
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs
index 4e94a3eeb46..25148dfc020 100644
--- a/src/test/compile-fail/variance-covariant-self-trait-match.rs
+++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs
@@ -10,6 +10,9 @@
 
 #![allow(dead_code)]
 
+// Test that even when `Self` is only used in covariant position, it
+// is treated as invariant.
+
 trait Get {
     fn get() -> Self;
 }
@@ -17,7 +20,8 @@ trait Get {
 fn get_min_from_max<'min, 'max, G>()
     where 'max : 'min, G : 'max, &'max G : Get
 {
-    impls_get::<&'min G>();
+    // Previously OK, now an error as traits are invariant.
+    impls_get::<&'min G>(); //~ ERROR mismatched types
 }
 
 fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/compile-fail/variance-region-bounds.rs b/src/test/compile-fail/variance-region-bounds.rs
index 96ae201f6ae..dfa5dc14441 100644
--- a/src/test/compile-fail/variance-region-bounds.rs
+++ b/src/test/compile-fail/variance-region-bounds.rs
@@ -13,11 +13,11 @@
 #![feature(rustc_attrs)]
 
 #[rustc_variance]
-trait Foo: 'static { //~ ERROR types=[[];[-];[]]
+trait Foo: 'static { //~ ERROR types=[[];[o];[]]
 }
 
 #[rustc_variance]
-trait Bar<T> { //~ ERROR types=[[+];[-];[]]
+trait Bar<T> { //~ ERROR types=[[o];[o];[]]
     fn do_it(&self)
         where T: 'static;
 }
diff --git a/src/test/compile-fail/variance-regions-unused-direct.rs b/src/test/compile-fail/variance-regions-unused-direct.rs
index 396e7765206..037fff72c80 100644
--- a/src/test/compile-fail/variance-regions-unused-direct.rs
+++ b/src/test/compile-fail/variance-regions-unused-direct.rs
@@ -18,7 +18,7 @@ struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used
     field: &'a [i32]
 }
 
-trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used
+trait Trait<'a, 'd> { // OK on traits
     fn method(&'a self);
 }
 
diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs
index 88b50058b65..222d8338aa2 100644
--- a/src/test/compile-fail/variance-trait-bounds.rs
+++ b/src/test/compile-fail/variance-trait-bounds.rs
@@ -16,12 +16,12 @@
 // influence variance.
 
 #[rustc_variance]
-trait Getter<T> { //~ ERROR types=[[+];[-];[]]
+trait Getter<T> { //~ ERROR types=[[o];[o];[]]
     fn get(&self) -> T;
 }
 
 #[rustc_variance]
-trait Setter<T> { //~ ERROR types=[[-];[-];[]]
+trait Setter<T> { //~ ERROR types=[[o];[o];[]]
     fn get(&self, T);
 }
 
@@ -37,16 +37,16 @@ enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[];[]]
 }
 
 #[rustc_variance]
-trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[-, +];[-];[]]
+trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[o, o];[o];[]]
     fn getter(&self, u: U) -> T;
 }
 
 #[rustc_variance]
-trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[+];[-];[]]
+trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[o];[o];[]]
 }
 
 #[rustc_variance]
-trait TestTrait3<U> { //~ ERROR types=[[-];[-];[]]
+trait TestTrait3<U> { //~ ERROR types=[[o];[o];[]]
     fn getter<T:Getter<U>>(&self);
 }
 
diff --git a/src/test/compile-fail/variance-trait-matching.rs b/src/test/compile-fail/variance-trait-matching.rs
index ec020f18818..49dc1e68c22 100644
--- a/src/test/compile-fail/variance-trait-matching.rs
+++ b/src/test/compile-fail/variance-trait-matching.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,22 +8,43 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Issue #5781. Tests that subtyping is handled properly in trait matching.
+// pretty-expanded FIXME #23616
 
-trait Make<'a> {
-    fn make(x: &'a mut isize) -> Self;
+#![allow(dead_code)]
+
+// Get<T> is covariant in T
+trait Get<T> {
+    fn get(&self) -> T;
+}
+
+struct Cloner<T:Clone> {
+    t: T
 }
 
-impl<'a> Make<'a> for &'a mut isize {
-    fn make(x: &'a mut isize) -> &'a mut isize {
-        x
+impl<T:Clone> Get<T> for Cloner<T> {
+    fn get(&self) -> T {
+        self.t.clone()
     }
 }
 
-fn f() -> &'static mut isize {
-    let mut x = 1;
-    let y: &'static mut isize = Make::make(&mut x);   //~ ERROR `x` does not live long enough
-    y
+fn get<'a, G>(get: &G) -> i32
+    where G : Get<&'a i32>
+{
+    // This fails to type-check because, without variance, we can't
+    // use `G : Get<&'a i32>` as evidence that `G : Get<&'b i32>`,
+    // even if `'a : 'b`.
+    pick(get, &22) //~ ERROR cannot infer
 }
 
-fn main() {}
+fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32
+    where G : Get<&'b i32>
+{
+    let v = *get.get();
+    if v % 2 != 0 { v } else { *if_odd }
+}
+
+fn main() {
+    let x = Cloner { t: &23 };
+    let y = get(&x);
+    assert_eq!(y, 23);
+}
diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs
index d53e4cd7610..a02f20656e7 100644
--- a/src/test/compile-fail/variance-types-bounds.rs
+++ b/src/test/compile-fail/variance-types-bounds.rs
@@ -37,12 +37,12 @@ struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[];[]]
 }
 
 #[rustc_variance]
-trait Getter<A> { //~ ERROR types=[[+];[-];[]]
+trait Getter<A> { //~ ERROR types=[[o];[o];[]]
     fn get(&self) -> A;
 }
 
 #[rustc_variance]
-trait Setter<A> { //~ ERROR types=[[-];[o];[]]
+trait Setter<A> { //~ ERROR types=[[o];[o];[]]
     fn set(&mut self, a: A);
 }
 
@@ -53,7 +53,7 @@ trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
 }
 
 #[rustc_variance]
-trait GetterInTypeBound<A> { //~ ERROR types=[[-];[-];[]]
+trait GetterInTypeBound<A> { //~ ERROR types=[[o];[o];[]]
     // Here, the use of `A` in the method bound *does* affect
     // variance.  Think of it as if the method requested a dictionary
     // for `T:Getter<A>`.  Since this dictionary is an input, it is
@@ -63,12 +63,12 @@ trait GetterInTypeBound<A> { //~ ERROR types=[[-];[-];[]]
 }
 
 #[rustc_variance]
-trait SetterInTypeBound<A> { //~ ERROR types=[[+];[-];[]]
+trait SetterInTypeBound<A> { //~ ERROR types=[[o];[o];[]]
     fn do_it<T:Setter<A>>(&self);
 }
 
 #[rustc_variance]
-struct TestObject<A, R> { //~ ERROR types=[[-, +];[];[]]
+struct TestObject<A, R> { //~ ERROR types=[[o, o];[];[]]
     n: Box<Setter<A>+Send>,
     m: Box<Getter<R>+Send>,
 }
diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs
index 5f504226370..407282e5ce0 100644
--- a/src/test/compile-fail/variance-unused-region-param.rs
+++ b/src/test/compile-fail/variance-unused-region-param.rs
@@ -12,6 +12,6 @@
 
 struct SomeStruct<'a> { x: u32 } //~ ERROR parameter `'a` is never used
 enum SomeEnum<'a> { Nothing } //~ ERROR parameter `'a` is never used
-trait SomeTrait<'a> { fn foo(&self); } //~ ERROR parameter `'a` is never used
+trait SomeTrait<'a> { fn foo(&self); } // OK on traits.
 
 fn main() {}
diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs
index 2e867ec3c93..862d842d62c 100644
--- a/src/test/compile-fail/variance-unused-type-param.rs
+++ b/src/test/compile-fail/variance-unused-type-param.rs
@@ -21,10 +21,6 @@ enum SomeEnum<A> { Nothing }
 //~^ ERROR parameter `A` is never used
 //~| HELP PhantomData
 
-trait SomeTrait<A> { fn foo(&self); }
-//~^ ERROR parameter `A` is never used
-//~| HELP PhantomFn
-
 // Here T might *appear* used, but in fact it isn't.
 enum ListCell<T> {
 //~^ ERROR parameter `T` is never used
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs
index f418d5d1fb7..563fe79e537 100644
--- a/src/test/run-make/simd-ffi/simd.rs
+++ b/src/test/run-make/simd-ffi/simd.rs
@@ -70,14 +70,10 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
 }
 
 #[lang = "sized"]
-pub trait Sized : PhantomFn<Self> {}
+pub trait Sized { }
 
 #[lang = "copy"]
-pub trait Copy : PhantomFn<Self> {}
-
-#[lang="phantom_fn"]
-pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
+pub trait Copy { }
 
 mod core {
     pub mod marker {
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index b13c41be559..9dbae193388 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -11,15 +11,11 @@
 #![feature(lang_items, no_std)]
 #![no_std]
 
-#[lang="phantom_fn"]
-trait PhantomFn<A:?Sized,R:?Sized=()> { }
-impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
-
 #[lang="copy"]
-trait Copy : PhantomFn<Self> { }
+trait Copy { }
 
 #[lang="sized"]
-trait Sized : PhantomFn<Self>  { }
+trait Sized { }
 
 #[lang="start"]
 fn start(_main: *const u8, _argc: isize, _argv: *const *const u8) -> isize { 0 }
diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/run-pass/coherence-subtyping.rs
index 897cb083f84..082a39f5631 100644
--- a/src/test/compile-fail/coherence-subtyping.rs
+++ b/src/test/run-pass/coherence-subtyping.rs
@@ -16,7 +16,6 @@ trait Contravariant {
 }
 
 impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) {
-    //~^ ERROR E0119
 }
 
 impl Contravariant for for<'a> fn(&'a u8, &'a u8) {
@@ -29,7 +28,6 @@ trait Covariant {
 }
 
 impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) {
-    //~^ ERROR E0119
 }
 
 impl Covariant for for<'a> fn(&'a u8, &'a u8) {
@@ -38,7 +36,7 @@ impl Covariant for for<'a> fn(&'a u8, &'a u8) {
 ///////////////////////////////////////////////////////////////////////////
 
 trait Invariant {
-    fn foo(&self) -> Self { }
+    fn foo(&self) { }
 }
 
 impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) {
diff --git a/src/test/run-pass/coherence_copy_like.rs b/src/test/run-pass/coherence_copy_like.rs
index db9893613ad..71db5225ecc 100644
--- a/src/test/run-pass/coherence_copy_like.rs
+++ b/src/test/run-pass/coherence_copy_like.rs
@@ -15,11 +15,9 @@
 
 extern crate coherence_copy_like_lib as lib;
 
-use std::marker::MarkerTrait;
-
 struct MyType { x: i32 }
 
-trait MyTrait : MarkerTrait { }
+trait MyTrait { }
 impl<T: lib::MyCopy> MyTrait for T { }
 impl MyTrait for MyType { }
 impl<'a> MyTrait for &'a MyType { }
diff --git a/src/test/run-pass/cycle-generic-bound.rs b/src/test/run-pass/cycle-generic-bound.rs
index 94e4665bb86..86b41284cdf 100644
--- a/src/test/run-pass/cycle-generic-bound.rs
+++ b/src/test/run-pass/cycle-generic-bound.rs
@@ -12,9 +12,7 @@
 
 // pretty-expanded FIXME #23616
 
-use std::marker::PhantomFn;
-
-trait Chromosome<X: Chromosome<i32>> : PhantomFn<(Self,X)> {
+trait Chromosome<X: Chromosome<i32>> {
 }
 
 fn main() { }
diff --git a/src/test/run-pass/issue-22356.rs b/src/test/run-pass/issue-22356.rs
index a54490386d0..51a871d59b3 100644
--- a/src/test/run-pass/issue-22356.rs
+++ b/src/test/run-pass/issue-22356.rs
@@ -10,7 +10,7 @@
 
 // pretty-expanded FIXME #23616
 
-use std::marker::{PhantomData, PhantomFn};
+use std::marker::PhantomData;
 
 pub struct Handle<T, I>(T, I);
 
@@ -34,7 +34,7 @@ impl<D: Device, T> BufferHandle<D, T> {
 
 pub type RawBufferHandle<D: Device> = Handle<<D as Device>::Buffer, String>;
 
-pub trait Device: PhantomFn<Self> {
+pub trait Device {
     type Buffer;
 }
 
diff --git a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
index 9aed9155124..0ffbc432aae 100644
--- a/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
+++ b/src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs
@@ -27,9 +27,7 @@ pub trait Decoder<'v> {
     fn read(&mut self) -> Value<'v>;
 }
 
-pub trait Decodable<'v, D: Decoder<'v>>
-    : marker::PhantomFn<(), &'v isize>
-{
+pub trait Decodable<'v, D: Decoder<'v>> {
     fn decode(d: &mut D) -> Self;
 }
 
diff --git a/src/test/run-pass/traits-conditional-dispatch.rs b/src/test/run-pass/traits-conditional-dispatch.rs
index 0190b7b7b96..0a6b9da74f2 100644
--- a/src/test/run-pass/traits-conditional-dispatch.rs
+++ b/src/test/run-pass/traits-conditional-dispatch.rs
@@ -17,13 +17,11 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-use std::marker::MarkerTrait;
-
 trait Get {
     fn get(&self) -> Self;
 }
 
-trait MyCopy : MarkerTrait { fn copy(&self) -> Self; }
+trait MyCopy { fn copy(&self) -> Self; }
 impl MyCopy for u16 { fn copy(&self) -> Self { *self } }
 impl MyCopy for u32 { fn copy(&self) -> Self { *self } }
 impl MyCopy for i32 { fn copy(&self) -> Self { *self } }
diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs
index 8ff8169ef49..449d6b37e9f 100644
--- a/src/test/run-pass/unsized.rs
+++ b/src/test/run-pass/unsized.rs
@@ -12,17 +12,17 @@
 
 // pretty-expanded FIXME #23616
 
-use std::marker::{PhantomData, PhantomFn};
+use std::marker::PhantomData;
 
-trait T1 : PhantomFn<Self> { }
-pub trait T2 : PhantomFn<Self> { }
-trait T3<X: T1> : T2 + PhantomFn<X> { }
-trait T4<X: ?Sized> : PhantomFn<(Self,X)> {}
-trait T5<X: ?Sized, Y> : PhantomFn<(Self,X,Y)> {}
-trait T6<Y, X: ?Sized> : PhantomFn<(Self,X,Y)> {}
-trait T7<X: ?Sized, Y: ?Sized> : PhantomFn<(Self,X,Y)> {}
-trait T8<X: ?Sized+T2> : PhantomFn<(Self,X)> {}
-trait T9<X: T2 + ?Sized> : PhantomFn<(Self,X)> {}
+trait T1  { }
+pub trait T2  { }
+trait T3<X: T1> : T2 { }
+trait T4<X: ?Sized> { }
+trait T5<X: ?Sized, Y> { }
+trait T6<Y, X: ?Sized> { }
+trait T7<X: ?Sized, Y: ?Sized> { }
+trait T8<X: ?Sized+T2> { }
+trait T9<X: T2 + ?Sized> { }
 struct S1<X: ?Sized>(PhantomData<X>);
 enum E<X: ?Sized> { E1(PhantomData<X>) }
 impl <X: ?Sized> T1 for S1<X> {}
diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs
deleted file mode 100644
index 5a179bfc7d4..00000000000
--- a/src/test/run-pass/variance-trait-matching.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// pretty-expanded FIXME #23616
-
-#![allow(dead_code)]
-
-// Get<T> is covariant in T
-trait Get<T> {
-    fn get(&self) -> T;
-}
-
-struct Cloner<T:Clone> {
-    t: T
-}
-
-impl<T:Clone> Get<T> for Cloner<T> {
-    fn get(&self) -> T {
-        self.t.clone()
-    }
-}
-
-fn get<'a, G>(get: &G) -> i32
-    where G : Get<&'a i32>
-{
-    // This call only type checks if we can use `G : Get<&'a i32>` as
-    // evidence that `G : Get<&'b i32>` where `'a : 'b`.
-    pick(get, &22)
-}
-
-fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32
-    where G : Get<&'b i32>
-{
-    let v = *get.get();
-    if v % 2 != 0 { v } else { *if_odd }
-}
-
-fn main() {
-    let x = Cloner { t: &23 };
-    let y = get(&x);
-    assert_eq!(y, 23);
-}
diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs
index 8535d76d471..eb95b13d3fa 100644
--- a/src/test/run-pass/where-for-self.rs
+++ b/src/test/run-pass/where-for-self.rs
@@ -13,18 +13,13 @@
 
 // pretty-expanded FIXME #23616
 
-use std::marker::PhantomFn;
-
 static mut COUNT: u32 = 1;
 
-trait Bar<'a>
-    : PhantomFn<&'a ()>
-{
+trait Bar<'a> {
     fn bar(&self);
 }
 
 trait Baz<'a>
-    : PhantomFn<&'a ()>
 {
     fn baz(&self);
 }