about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-02-18 15:52:01 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-02-18 15:52:01 -0800
commit1506b34e0c52b098158541d2ba9e334df1ce4812 (patch)
treea9ead87eacaf0acafdb0c4f72c334c2d5601b0ca
parent3e7a04cb3cac2b803dc8188d9a55ba1836404ea3 (diff)
parent9f8b9d6847ab02f7f1c28c84988ceae4c0a10f26 (diff)
downloadrust-1506b34e0c52b098158541d2ba9e334df1ce4812.tar.gz
rust-1506b34e0c52b098158541d2ba9e334df1ce4812.zip
rollup merge of #22286: nikomatsakis/variance-4b
Conflicts:
	src/librustc/middle/infer/combine.rs
	src/librustc_typeck/check/wf.rs
-rw-r--r--src/doc/reference.md10
-rw-r--r--src/libarena/lib.rs6
-rw-r--r--src/libcollections/btree/map.rs17
-rw-r--r--src/libcollections/btree/node.rs84
-rw-r--r--src/libcollections/enum_set.rs24
-rw-r--r--src/libcollections/vec.rs38
-rw-r--r--src/libcollections/vec_deque.rs60
-rw-r--r--src/libcollections/vec_map.rs2
-rw-r--r--src/libcore/atomic.rs5
-rw-r--r--src/libcore/fmt/mod.rs7
-rw-r--r--src/libcore/iter.rs11
-rw-r--r--src/libcore/marker.rs386
-rw-r--r--src/libcore/nonzero.rs9
-rw-r--r--src/libcore/ptr.rs52
-rw-r--r--src/libcore/slice.rs14
-rw-r--r--src/libcoretest/mem.rs2
-rw-r--r--src/libcoretest/ptr.rs4
-rw-r--r--src/libflate/lib.rs8
-rw-r--r--src/librand/distributions/mod.rs11
-rw-r--r--src/librand/lib.rs4
-rw-r--r--src/librustc/middle/expr_use_visitor.rs13
-rw-r--r--src/librustc/middle/infer/bivariate.rs145
-rw-r--r--src/librustc/middle/infer/combine.rs146
-rw-r--r--src/librustc/middle/infer/equate.rs27
-rw-r--r--src/librustc/middle/infer/error_reporting.rs16
-rw-r--r--src/librustc/middle/infer/glb.rs47
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs4
-rw-r--r--src/librustc/middle/infer/lub.rs47
-rw-r--r--src/librustc/middle/infer/mod.rs6
-rw-r--r--src/librustc/middle/infer/sub.rs48
-rw-r--r--src/librustc/middle/infer/type_variable.rs10
-rw-r--r--src/librustc/middle/infer/unify.rs9
-rw-r--r--src/librustc/middle/lang_items.rs3
-rw-r--r--src/librustc/middle/traits/coherence.rs101
-rw-r--r--src/librustc/middle/traits/mod.rs11
-rw-r--r--src/librustc/middle/traits/select.rs13
-rw-r--r--src/librustc/middle/ty.rs7
-rw-r--r--src/librustc_typeck/check/method/suggest.rs4
-rw-r--r--src/librustc_typeck/check/regionck.rs14
-rw-r--r--src/librustc_typeck/check/wf.rs158
-rw-r--r--src/librustc_typeck/collect.rs56
-rw-r--r--src/librustc_typeck/constrained_type_params.rs61
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustc_typeck/variance.rs394
-rw-r--r--src/libstd/collections/hash/state.rs7
-rw-r--r--src/libstd/collections/hash/table.rs62
-rw-r--r--src/libstd/old_io/mod.rs10
-rw-r--r--src/libstd/thread.rs6
-rw-r--r--src/libsyntax/std_inject.rs11
-rw-r--r--src/libterm/lib.rs1
-rw-r--r--src/test/auxiliary/coherence-orphan-lib.rs2
-rw-r--r--src/test/auxiliary/default_type_params_xc.rs3
-rw-r--r--src/test/auxiliary/inner_static.rs12
-rw-r--r--src/test/auxiliary/issue-14421.rs5
-rw-r--r--src/test/auxiliary/issue-16643.rs2
-rw-r--r--src/test/auxiliary/issue-17662.rs2
-rw-r--r--src/test/auxiliary/issue-2380.rs5
-rw-r--r--src/test/auxiliary/issue-2526.rs8
-rw-r--r--src/test/auxiliary/issue_20389.rs1
-rw-r--r--src/test/auxiliary/issue_3907.rs4
-rw-r--r--src/test/auxiliary/issue_8401.rs4
-rw-r--r--src/test/auxiliary/issue_9123.rs1
-rw-r--r--src/test/auxiliary/lang-item-public.rs10
-rw-r--r--src/test/auxiliary/lint_stability.rs2
-rw-r--r--src/test/auxiliary/nested_item.rs2
-rw-r--r--src/test/auxiliary/orphan_check_diagnostics.rs2
-rw-r--r--src/test/auxiliary/overloaded_autoderef_xc.rs5
-rw-r--r--src/test/auxiliary/private_trait_xc.rs2
-rw-r--r--src/test/auxiliary/svh-a-base.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-lit.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-significant-cfg.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-trait-bound.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-arg.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-ret.rs6
-rw-r--r--src/test/auxiliary/svh-a-change-type-static.rs6
-rw-r--r--src/test/auxiliary/svh-a-comment.rs6
-rw-r--r--src/test/auxiliary/svh-a-doc.rs6
-rw-r--r--src/test/auxiliary/svh-a-macro.rs6
-rw-r--r--src/test/auxiliary/svh-a-no-change.rs6
-rw-r--r--src/test/auxiliary/svh-a-redundant-cfg.rs6
-rw-r--r--src/test/auxiliary/svh-a-whitespace.rs6
-rw-r--r--src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs4
-rw-r--r--src/test/auxiliary/trait_impl_conflict.rs2
-rw-r--r--src/test/auxiliary/use_from_trait_xc.rs2
-rw-r--r--src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs6
-rw-r--r--src/test/compile-fail/associated-types-coherence-failure.rs3
-rw-r--r--src/test/compile-fail/associated-types-eq-expr-path.rs2
-rw-r--r--src/test/compile-fail/associated-types-issue-17359.rs2
-rw-r--r--src/test/compile-fail/associated-types-multiple-types-one-trait.rs2
-rw-r--r--src/test/compile-fail/associated-types-no-suitable-supertrait.rs2
-rw-r--r--src/test/compile-fail/associated-types-path-2.rs2
-rw-r--r--src/test/compile-fail/associated-types-unconstrained.rs2
-rw-r--r--src/test/compile-fail/bad-mid-path-type-params.rs7
-rw-r--r--src/test/compile-fail/bad-sized.rs2
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs5
-rw-r--r--src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs4
-rw-r--r--src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs8
-rw-r--r--src/test/compile-fail/coherence-subtyping.rs50
-rw-r--r--src/test/compile-fail/cross-borrow-trait.rs2
-rw-r--r--src/test/compile-fail/destructure-trait-ref.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce1.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce2.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coerce3.rs2
-rw-r--r--src/test/compile-fail/dst-bad-coercions.rs4
-rw-r--r--src/test/compile-fail/dst-object-from-unsized-type.rs2
-rw-r--r--src/test/compile-fail/exclusive-drop-and-copy.rs2
-rw-r--r--src/test/compile-fail/generic-impl-less-params-with-defaults.rs7
-rw-r--r--src/test/compile-fail/generic-impl-more-params-with-defaults.rs7
-rw-r--r--src/test/compile-fail/generic-lifetime-trait-impl.rs5
-rw-r--r--src/test/compile-fail/generic-type-less-params-with-defaults.rs5
-rw-r--r--src/test/compile-fail/generic-type-more-params-with-defaults.rs5
-rw-r--r--src/test/compile-fail/generic-type-params-name-repr.rs8
-rw-r--r--src/test/compile-fail/issue-11515.rs2
-rw-r--r--src/test/compile-fail/issue-13853-2.rs4
-rw-r--r--src/test/compile-fail/issue-13853-3.rs5
-rw-r--r--src/test/compile-fail/issue-13853.rs4
-rw-r--r--src/test/compile-fail/issue-14285.rs4
-rw-r--r--src/test/compile-fail/issue-14853.rs3
-rw-r--r--src/test/compile-fail/issue-16747.rs4
-rw-r--r--src/test/compile-fail/issue-17431-4.rs4
-rw-r--r--src/test/compile-fail/issue-17431-5.rs4
-rw-r--r--src/test/compile-fail/issue-17551.rs6
-rw-r--r--src/test/compile-fail/issue-17904-2.rs16
-rw-r--r--src/test/compile-fail/issue-18107.rs4
-rw-r--r--src/test/compile-fail/issue-18611.rs4
-rw-r--r--src/test/compile-fail/issue-18783.rs1
-rw-r--r--src/test/compile-fail/issue-18819.rs4
-rw-r--r--src/test/compile-fail/issue-19660.rs6
-rw-r--r--src/test/compile-fail/issue-2063.rs3
-rw-r--r--src/test/compile-fail/issue-20831-debruijn.rs5
-rw-r--r--src/test/compile-fail/issue-2611-4.rs4
-rw-r--r--src/test/compile-fail/issue-3008-3.rs4
-rw-r--r--src/test/compile-fail/issue-4972.rs4
-rw-r--r--src/test/compile-fail/issue-5035-2.rs4
-rw-r--r--src/test/compile-fail/issue-5543.rs4
-rw-r--r--src/test/compile-fail/issue-5883.rs6
-rw-r--r--src/test/compile-fail/issue-6458.rs6
-rw-r--r--src/test/compile-fail/issue-7575.rs8
-rw-r--r--src/test/compile-fail/issue-8727.rs10
-rw-r--r--src/test/compile-fail/kindck-copy.rs4
-rw-r--r--src/test/compile-fail/kindck-impl-type-params-2.rs4
-rw-r--r--src/test/compile-fail/kindck-impl-type-params.rs20
-rw-r--r--src/test/compile-fail/kindck-send-object.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object1.rs4
-rw-r--r--src/test/compile-fail/kindck-send-object2.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs4
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs20
-rw-r--r--src/test/compile-fail/lint-non-camel-case-types.rs1
-rw-r--r--src/test/compile-fail/lint-stability.rs4
-rw-r--r--src/test/compile-fail/lint-visible-private-types.rs8
-rw-r--r--src/test/compile-fail/liveness-use-after-send.rs4
-rw-r--r--src/test/compile-fail/map-types.rs5
-rw-r--r--src/test/compile-fail/method-ambig-one-trait-coerce.rs50
-rw-r--r--src/test/compile-fail/object-does-not-impl-trait.rs3
-rw-r--r--src/test/compile-fail/object-lifetime-default-mybox.rs1
-rw-r--r--src/test/compile-fail/object-safety-no-static.rs2
-rw-r--r--src/test/compile-fail/on-unimplemented-bad-anno.rs18
-rw-r--r--src/test/compile-fail/on-unimplemented.rs6
-rw-r--r--src/test/compile-fail/orphan-check-diagnostics.rs2
-rw-r--r--src/test/compile-fail/priv-in-bad-locations.rs4
-rw-r--r--src/test/compile-fail/privacy-ns2.rs8
-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/region-object-lifetime-in-coercion.rs2
-rw-r--r--src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs5
-rw-r--r--src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs5
-rw-r--r--src/test/compile-fail/regions-bound-missing-bound-in-impl.rs5
-rw-r--r--src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs6
-rw-r--r--src/test/compile-fail/regions-close-associated-type-into-object.rs4
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-1.rs9
-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.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-4.rs6
-rw-r--r--src/test/compile-fail/regions-close-object-into-object-5.rs32
-rw-r--r--src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs4
-rw-r--r--src/test/compile-fail/regions-close-param-into-object.rs2
-rw-r--r--src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/regions-infer-covariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/regions-infer-invariance-due-to-decl.rs2
-rw-r--r--src/test/compile-fail/required-lang-item.rs6
-rw-r--r--src/test/compile-fail/shadowed-type-parameter.rs6
-rw-r--r--src/test/compile-fail/slightly-nice-generic-literal-messages.rs6
-rw-r--r--src/test/compile-fail/staticness-mismatch.rs2
-rw-r--r--src/test/compile-fail/trait-as-struct-constructor.rs2
-rw-r--r--src/test/compile-fail/trait-bounds-cant-coerce.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-1.rs14
-rw-r--r--src/test/compile-fail/trait-bounds-impl-comparison-2.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-not-on-bare-trait.rs1
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs4
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums.rs10
-rw-r--r--src/test/compile-fail/trait-bounds-sugar.rs3
-rw-r--r--src/test/compile-fail/trait-impl-1.rs4
-rw-r--r--src/test/compile-fail/trait-object-safety.rs1
-rw-r--r--src/test/compile-fail/trait-static-method-generic-inference.rs1
-rw-r--r--src/test/compile-fail/typeck-negative-impls-builtin.rs4
-rw-r--r--src/test/compile-fail/typeck_type_placeholder_mismatch.rs10
-rw-r--r--src/test/compile-fail/unboxed-closure-feature-gate.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-default.rs2
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-equiv.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs4
-rw-r--r--src/test/compile-fail/unboxed-closure-sugar-region.rs2
-rw-r--r--src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs6
-rw-r--r--src/test/compile-fail/unnecessary-private.rs4
-rw-r--r--src/test/compile-fail/unsized-inherent-impl-self-type.rs2
-rw-r--r--src/test/compile-fail/unsized-trait-impl-self-type.rs3
-rw-r--r--src/test/compile-fail/unsized-trait-impl-trait-arg.rs3
-rw-r--r--src/test/compile-fail/unsized3.rs5
-rw-r--r--src/test/compile-fail/unsized6.rs3
-rw-r--r--src/test/compile-fail/unsized7.rs8
-rw-r--r--src/test/compile-fail/unused-attr.rs4
-rw-r--r--src/test/compile-fail/useless-priv.rs8
-rw-r--r--src/test/compile-fail/useless-priv2.rs6
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-contravariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-contravariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-covariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-deprecated-markers.rs35
-rw-r--r--src/test/compile-fail/variance-invariant-arg-object.rs31
-rw-r--r--src/test/compile-fail/variance-invariant-arg-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-invariant-self-trait-match.rs31
-rw-r--r--src/test/compile-fail/variance-issue-20533.rs54
-rw-r--r--src/test/compile-fail/variance-regions-direct.rs1
-rw-r--r--src/test/compile-fail/variance-regions-indirect.rs4
-rw-r--r--src/test/compile-fail/variance-regions-unused-direct.rs (renamed from src/test/run-pass/regions-infer-bivariance.rs)17
-rw-r--r--src/test/compile-fail/variance-regions-unused-indirect.rs (renamed from src/test/run-pass/export-non-interference.rs)11
-rw-r--r--src/test/compile-fail/variance-trait-bounds.rs65
-rw-r--r--src/test/compile-fail/variance-trait-object-bound.rs2
-rw-r--r--src/test/compile-fail/variance-types-bounds.rs76
-rw-r--r--src/test/compile-fail/variance-types.rs52
-rw-r--r--src/test/compile-fail/variance-unused-region-param.rs17
-rw-r--r--src/test/compile-fail/variance-unused-type-param.rs36
-rw-r--r--src/test/compile-fail/variance-use-contravariant-struct-1.rs26
-rw-r--r--src/test/compile-fail/variance-use-contravariant-struct-2.rs27
-rw-r--r--src/test/compile-fail/variance-use-covariant-struct-1.rs23
-rw-r--r--src/test/compile-fail/variance-use-covariant-struct-2.rs26
-rw-r--r--src/test/compile-fail/variance-use-invariant-struct-1.rs33
-rw-r--r--src/test/compile-fail/visible-private-types-generics.rs4
-rw-r--r--src/test/compile-fail/visible-private-types-supertrait.rs4
-rw-r--r--src/test/compile-fail/where-clause-method-substituion.rs4
-rw-r--r--src/test/compile-fail/where-clauses-not-parameter.rs4
-rw-r--r--src/test/debuginfo/type-names.rs17
-rw-r--r--src/test/pretty/empty-impl.rs4
-rw-r--r--src/test/pretty/path-type-bounds.rs4
-rw-r--r--src/test/run-fail/bug-811.rs4
-rw-r--r--src/test/run-make/rustdoc-json/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-negative-impl/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-search-index/index.rs2
-rw-r--r--src/test/run-make/rustdoc-smoke/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-viewpath-self/foo.rs2
-rw-r--r--src/test/run-make/rustdoc-where/foo.rs15
-rw-r--r--src/test/run-make/save-analysis/foo.rs1
-rwxr-xr-xsrc/test/run-make/simd-ffi/simd.rs8
-rw-r--r--src/test/run-make/symbols-are-reasonable/lib.rs2
-rw-r--r--src/test/run-make/target-specs/foo.rs8
-rw-r--r--src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs2
-rw-r--r--src/test/run-pass-valgrind/dst-dtor-1.rs2
-rw-r--r--src/test/run-pass/associated-types-basic.rs4
-rw-r--r--src/test/run-pass/associated-types-conditional-dispatch.rs7
-rw-r--r--src/test/run-pass/associated-types-issue-20371.rs4
-rw-r--r--src/test/run-pass/associated-types-issue-21212.rs3
-rw-r--r--src/test/run-pass/associated-types-nested-projections.rs5
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds-binding.rs6
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs10
-rw-r--r--src/test/run-pass/associated-types-normalize-in-bounds.rs10
-rw-r--r--src/test/run-pass/associated-types-normalize-unifield-struct.rs5
-rw-r--r--src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-object-type.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-supertrait.rs2
-rw-r--r--src/test/run-pass/associated-types-projection-in-where-clause.rs2
-rw-r--r--src/test/run-pass/associated-types-ref-in-struct-literal.rs2
-rw-r--r--src/test/run-pass/associated-types-resolve-lifetime.rs2
-rw-r--r--src/test/run-pass/associated-types-struct-field-named.rs2
-rw-r--r--src/test/run-pass/associated-types-struct-field-numbered.rs2
-rw-r--r--src/test/run-pass/associated-types-sugar-path.rs3
-rw-r--r--src/test/run-pass/borrowck-trait-lifetime.rs5
-rw-r--r--src/test/run-pass/bug-7295.rs6
-rw-r--r--src/test/run-pass/builtin-superkinds-in-metadata.rs1
-rw-r--r--src/test/run-pass/builtin-superkinds-phantom-typaram.rs6
-rw-r--r--src/test/run-pass/class-typarams.rs7
-rw-r--r--src/test/run-pass/dst-coercions.rs2
-rw-r--r--src/test/run-pass/enum-null-pointer-opt.rs2
-rw-r--r--src/test/run-pass/explicit-self-generic.rs8
-rw-r--r--src/test/run-pass/generic-default-type-params-cross-crate.rs10
-rw-r--r--src/test/run-pass/hrtb-opt-in-copy.rs4
-rw-r--r--src/test/run-pass/inner-static.rs6
-rw-r--r--src/test/run-pass/issue-10456.rs4
-rw-r--r--src/test/run-pass/issue-10802.rs2
-rw-r--r--src/test/run-pass/issue-10902.rs4
-rw-r--r--src/test/run-pass/issue-11205.rs2
-rw-r--r--src/test/run-pass/issue-11384.rs2
-rw-r--r--src/test/run-pass/issue-11612.rs2
-rw-r--r--src/test/run-pass/issue-11677.rs9
-rw-r--r--src/test/run-pass/issue-13105.rs4
-rw-r--r--src/test/run-pass/issue-14399.rs2
-rw-r--r--src/test/run-pass/issue-14589.rs7
-rw-r--r--src/test/run-pass/issue-14958.rs2
-rw-r--r--src/test/run-pass/issue-14959.rs8
-rw-r--r--src/test/run-pass/issue-15858.rs12
-rw-r--r--src/test/run-pass/issue-16596.rs2
-rw-r--r--src/test/run-pass/issue-16643.rs2
-rw-r--r--src/test/run-pass/issue-17662.rs6
-rw-r--r--src/test/run-pass/issue-17732.rs3
-rw-r--r--src/test/run-pass/issue-17771.rs2
-rw-r--r--src/test/run-pass/issue-17816.rs6
-rw-r--r--src/test/run-pass/issue-17904.rs4
-rw-r--r--src/test/run-pass/issue-18232.rs4
-rw-r--r--src/test/run-pass/issue-18906.rs2
-rw-r--r--src/test/run-pass/issue-19121.rs2
-rw-r--r--src/test/run-pass/issue-19129-2.rs2
-rw-r--r--src/test/run-pass/issue-19135.rs6
-rw-r--r--src/test/run-pass/issue-19358.rs2
-rw-r--r--src/test/run-pass/issue-19398.rs4
-rw-r--r--src/test/run-pass/issue-19479.rs6
-rw-r--r--src/test/run-pass/issue-19631.rs1
-rw-r--r--src/test/run-pass/issue-19632.rs1
-rw-r--r--src/test/run-pass/issue-20055-box-trait.rs4
-rw-r--r--src/test/run-pass/issue-20343.rs2
-rw-r--r--src/test/run-pass/issue-20763-1.rs5
-rw-r--r--src/test/run-pass/issue-20763-2.rs5
-rw-r--r--src/test/run-pass/issue-21363.rs1
-rw-r--r--src/test/run-pass/issue-21909.rs6
-rw-r--r--src/test/run-pass/issue-2311-2.rs5
-rw-r--r--src/test/run-pass/issue-2311.rs2
-rw-r--r--src/test/run-pass/issue-2312.rs2
-rw-r--r--src/test/run-pass/issue-2611-3.rs4
-rw-r--r--src/test/run-pass/issue-2734.rs4
-rw-r--r--src/test/run-pass/issue-2735.rs4
-rw-r--r--src/test/run-pass/issue-4107.rs12
-rw-r--r--src/test/run-pass/issue-5192.rs1
-rw-r--r--src/test/run-pass/issue-5708.rs4
-rw-r--r--src/test/run-pass/issue-6128.rs4
-rw-r--r--src/test/run-pass/issue-6318.rs4
-rw-r--r--src/test/run-pass/issue-7575.rs1
-rw-r--r--src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs5
-rw-r--r--src/test/run-pass/issue-7911.rs4
-rw-r--r--src/test/run-pass/issue-8248.rs4
-rw-r--r--src/test/run-pass/issue-8249.rs4
-rw-r--r--src/test/run-pass/issue-9719.rs8
-rw-r--r--src/test/run-pass/lint-cstack.rs2
-rw-r--r--src/test/run-pass/method-early-bound-lifetimes-on-self.rs8
-rw-r--r--src/test/run-pass/method-recursive-blanket-impl.rs8
-rw-r--r--src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs3
-rw-r--r--src/test/run-pass/overloaded-autoderef-vtable.rs6
-rw-r--r--src/test/run-pass/overloaded-calls-param-vtables.rs5
-rw-r--r--src/test/run-pass/parameterized-trait-with-bounds.rs8
-rw-r--r--src/test/run-pass/privacy-ns.rs3
-rw-r--r--src/test/run-pass/regions-assoc-type-static-bound.rs5
-rw-r--r--src/test/run-pass/regions-bound-lists-feature-gate-2.rs4
-rw-r--r--src/test/run-pass/regions-bound-lists-feature-gate.rs5
-rw-r--r--src/test/run-pass/regions-early-bound-lifetime-in-assoc-fn.rs6
-rw-r--r--src/test/run-pass/regions-early-bound-trait-param.rs6
-rw-r--r--src/test/run-pass/regions-issue-21422.rs25
-rw-r--r--src/test/run-pass/regions-no-bound-in-argument-cleanup.rs4
-rw-r--r--src/test/run-pass/regions-no-variance-from-fn-generics.rs10
-rw-r--r--src/test/run-pass/self-impl.rs1
-rw-r--r--src/test/run-pass/simple-match-generic-tag.rs9
-rw-r--r--src/test/run-pass/syntax-trait-polarity.rs6
-rw-r--r--src/test/run-pass/trailing-comma.rs4
-rw-r--r--src/test/run-pass/trait-bounds-basic.rs2
-rw-r--r--src/test/run-pass/trait-bounds-on-structs-and-enums.rs6
-rw-r--r--src/test/run-pass/trait-bounds-recursion.rs8
-rw-r--r--src/test/run-pass/trait-default-method-bound-subst4.rs1
-rw-r--r--src/test/run-pass/trait-impl.rs3
-rw-r--r--src/test/run-pass/trait-inheritance-num2.rs3
-rw-r--r--src/test/run-pass/trait-inheritance-static2.rs4
-rw-r--r--src/test/run-pass/trait-object-generics.rs11
-rw-r--r--src/test/run-pass/trait-static-method-overwriting.rs10
-rw-r--r--src/test/run-pass/unboxed-closures-infer-recursive-fn.rs6
-rw-r--r--src/test/run-pass/unique-object-move.rs2
-rw-r--r--src/test/run-pass/unsized.rs24
-rw-r--r--src/test/run-pass/unsized2.rs12
-rw-r--r--src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs34
-rw-r--r--src/test/run-pass/variance-trait-matching.rs49
-rw-r--r--src/test/run-pass/variance-vec-covariant.rs28
-rw-r--r--src/test/run-pass/visible-private-types-feature-gate.rs2
-rw-r--r--src/test/run-pass/where-clause-bounds-inconsistency.rs4
-rw-r--r--src/test/run-pass/where-clause-early-bound-lifetimes.rs2
-rw-r--r--src/test/run-pass/where-clause-method-substituion.rs4
-rw-r--r--src/test/run-pass/where-for-self.rs10
383 files changed, 3307 insertions, 1347 deletions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 3bbe60a77c9..db940947040 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -572,7 +572,7 @@ the final namespace qualifier is omitted.
 Two examples of paths with type arguments:
 
 ```
-# struct HashMap<K, V>;
+# struct HashMap<K, V>(K,V);
 # fn f() {
 # fn id<T>(t: T) -> T { t }
 type T = HashMap<i32,String>; // Type arguments used in a type expression
@@ -1599,7 +1599,7 @@ pointer values (pointing to a type for which an implementation of the given
 trait is in scope) to pointers to the trait name, used as a type.
 
 ```
-# trait Shape { }
+# trait Shape { fn dummy(&self) { } }
 # impl Shape for i32 { }
 # let mycircle = 0i32;
 let myshape: Box<Shape> = Box::new(mycircle) as Box<Shape>;
@@ -1630,8 +1630,8 @@ let x: f64 = Num::from_i32(42);
 Traits may inherit from other traits. For example, in
 
 ```
-trait Shape { fn area() -> f64; }
-trait Circle : Shape { fn radius() -> f64; }
+trait Shape { fn area(&self) -> f64; }
+trait Circle : Shape { fn radius(&self) -> f64; }
 ```
 
 the syntax `Circle : Shape` means that types that implement `Circle` must also
@@ -1725,7 +1725,7 @@ type parameters taken by the trait it implements. Implementation parameters
 are written after the `impl` keyword.
 
 ```
-# trait Seq<T> { }
+# trait Seq<T> { fn dummy(&self, _: T) { } }
 impl<T> Seq<T> for Vec<T> {
    /* ... */
 }
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 4cd3d587580..b43f9adfb26 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -96,7 +96,7 @@ pub struct Arena<'longer_than_self> {
     head: RefCell<Chunk>,
     copy_head: RefCell<Chunk>,
     chunks: RefCell<Vec<Chunk>>,
-    _invariant: marker::InvariantLifetime<'longer_than_self>,
+    _marker: marker::PhantomData<*mut &'longer_than_self()>,
 }
 
 impl<'a> Arena<'a> {
@@ -111,7 +111,7 @@ impl<'a> Arena<'a> {
             head: RefCell::new(chunk(initial_size, false)),
             copy_head: RefCell::new(chunk(initial_size, true)),
             chunks: RefCell::new(Vec::new()),
-            _invariant: marker::InvariantLifetime,
+            _marker: marker::PhantomData,
         }
     }
 }
@@ -361,6 +361,8 @@ pub struct TypedArena<T> {
 }
 
 struct TypedArenaChunk<T> {
+    marker: marker::PhantomData<T>,
+
     /// Pointer to the next arena segment.
     next: *mut TypedArenaChunk<T>,
 
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index c6cd6895728..7823f536c7a 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -512,13 +512,22 @@ mod stack {
     use super::super::node::handle;
     use vec::Vec;
 
+    struct InvariantLifetime<'id>(
+        marker::PhantomData<::core::cell::Cell<&'id ()>>);
+
+    impl<'id> InvariantLifetime<'id> {
+        fn new() -> InvariantLifetime<'id> {
+            InvariantLifetime(marker::PhantomData)
+        }
+    }
+
     /// A generic mutable reference, identical to `&mut` except for the fact that its lifetime
     /// parameter is invariant. This means that wherever an `IdRef` is expected, only an `IdRef`
     /// with the exact requested lifetime can be used. This is in contrast to normal references,
     /// where `&'static` can be used in any function expecting any lifetime reference.
     pub struct IdRef<'id, T: 'id> {
         inner: &'id mut T,
-        marker: marker::InvariantLifetime<'id>
+        _marker: InvariantLifetime<'id>,
     }
 
     impl<'id, T> Deref for IdRef<'id, T> {
@@ -560,7 +569,7 @@ mod stack {
     pub struct Pusher<'id, 'a, K:'a, V:'a> {
         map: &'a mut BTreeMap<K, V>,
         stack: Stack<K, V>,
-        marker: marker::InvariantLifetime<'id>
+        _marker: InvariantLifetime<'id>,
     }
 
     impl<'a, K, V> PartialSearchStack<'a, K, V> {
@@ -595,11 +604,11 @@ mod stack {
             let pusher = Pusher {
                 map: self.map,
                 stack: self.stack,
-                marker: marker::InvariantLifetime
+                _marker: InvariantLifetime::new(),
             };
             let node = IdRef {
                 inner: unsafe { &mut *self.next },
-                marker: marker::InvariantLifetime
+                _marker: InvariantLifetime::new(),
             };
 
             closure(pusher, node)
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 8f5ee35fcb2..f0fc12da727 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -20,10 +20,11 @@ use core::prelude::*;
 
 use core::cmp::Ordering::{Greater, Less, Equal};
 use core::iter::Zip;
+use core::marker::PhantomData;
 use core::ops::{Deref, DerefMut, Index, IndexMut};
 use core::ptr::Unique;
 use core::{slice, mem, ptr, cmp, num, raw};
-use alloc::heap;
+use alloc::heap::{self, EMPTY};
 
 use borrow::Borrow;
 
@@ -58,8 +59,8 @@ pub struct Node<K, V> {
     keys: Unique<K>,
     vals: Unique<V>,
 
-    // In leaf nodes, this will be null, and no space will be allocated for edges.
-    edges: Unique<Node<K, V>>,
+    // In leaf nodes, this will be None, and no space will be allocated for edges.
+    edges: Option<Unique<Node<K, V>>>,
 
     // At any given time, there will be `_len` keys, `_len` values, and (in an internal node)
     // `_len + 1` edges. In a leaf node, there will never be any edges.
@@ -279,8 +280,11 @@ impl<T> Drop for RawItems<T> {
 #[unsafe_destructor]
 impl<K, V> Drop for Node<K, V> {
     fn drop(&mut self) {
-        if self.keys.ptr.is_null() {
-            // We have already cleaned up this node.
+        if self.keys.is_null() {
+            // Since we have #[unsafe_no_drop_flag], we have to watch
+            // out for a null value being stored in self.keys. (Using
+            // null is technically a violation of the `Unique`
+            // requirements, though.)
             return;
         }
 
@@ -293,7 +297,7 @@ impl<K, V> Drop for Node<K, V> {
             self.destroy();
         }
 
-        self.keys.ptr = ptr::null_mut();
+        self.keys = unsafe { Unique::new(0 as *mut K) };
     }
 }
 
@@ -309,9 +313,9 @@ impl<K, V> Node<K, V> {
         let (vals_offset, edges_offset) = calculate_offsets_generic::<K, V>(capacity, false);
 
         Node {
-            keys: Unique(buffer as *mut K),
-            vals: Unique(buffer.offset(vals_offset as isize) as *mut V),
-            edges: Unique(buffer.offset(edges_offset as isize) as *mut Node<K, V>),
+            keys: Unique::new(buffer as *mut K),
+            vals: Unique::new(buffer.offset(vals_offset as isize) as *mut V),
+            edges: Some(Unique::new(buffer.offset(edges_offset as isize) as *mut Node<K, V>)),
             _len: 0,
             _capacity: capacity,
         }
@@ -327,9 +331,9 @@ impl<K, V> Node<K, V> {
         let (vals_offset, _) = calculate_offsets_generic::<K, V>(capacity, true);
 
         Node {
-            keys: Unique(buffer as *mut K),
-            vals: Unique(unsafe { buffer.offset(vals_offset as isize) as *mut V }),
-            edges: Unique(ptr::null_mut()),
+            keys: unsafe { Unique::new(buffer as *mut K) },
+            vals: unsafe { Unique::new(buffer.offset(vals_offset as isize) as *mut V) },
+            edges: None,
             _len: 0,
             _capacity: capacity,
         }
@@ -338,18 +342,18 @@ impl<K, V> Node<K, V> {
     unsafe fn destroy(&mut self) {
         let (alignment, size) =
                 calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
-        heap::deallocate(self.keys.ptr as *mut u8, size, alignment);
+        heap::deallocate(*self.keys as *mut u8, size, alignment);
     }
 
     #[inline]
     pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
         unsafe {(
             mem::transmute(raw::Slice {
-                data: self.keys.ptr,
+                data: *self.keys as *const K,
                 len: self.len()
             }),
             mem::transmute(raw::Slice {
-                data: self.vals.ptr,
+                data: *self.vals as *const V,
                 len: self.len()
             })
         )}
@@ -368,8 +372,12 @@ impl<K, V> Node<K, V> {
             &[]
         } else {
             unsafe {
+                let data = match self.edges {
+                    None => heap::EMPTY as *const Node<K,V>,
+                    Some(ref p) => **p as *const Node<K,V>,
+                };
                 mem::transmute(raw::Slice {
-                    data: self.edges.ptr,
+                    data: data,
                     len: self.len() + 1
                 })
             }
@@ -525,7 +533,8 @@ impl<K: Clone, V: Clone> Clone for Node<K, V> {
 #[derive(Copy)]
 pub struct Handle<NodeRef, Type, NodeType> {
     node: NodeRef,
-    index: usize
+    index: usize,
+    marker: PhantomData<(Type, NodeType)>,
 }
 
 pub mod handle {
@@ -549,8 +558,8 @@ impl<K: Ord, V> Node<K, V> {
         // For the B configured as of this writing (B = 6), binary search was *significantly*
         // worse for usizes.
         match node.as_slices_internal().search_linear(key) {
-            (index, true) => Found(Handle { node: node, index: index }),
-            (index, false) => GoDown(Handle { node: node, index: index }),
+            (index, true) => Found(Handle { node: node, index: index, marker: PhantomData }),
+            (index, false) => GoDown(Handle { node: node, index: index, marker: PhantomData }),
         }
     }
 }
@@ -587,7 +596,7 @@ impl <K, V> Node<K, V> {
 
     /// If the node has any children
     pub fn is_leaf(&self) -> bool {
-        self.edges.ptr.is_null()
+        self.edges.is_none()
     }
 
     /// if the node has too few elements
@@ -619,7 +628,8 @@ impl<K, V, NodeRef, Type, NodeType> Handle<NodeRef, Type, NodeType> where
     pub fn as_raw(&mut self) -> Handle<*mut Node<K, V>, Type, NodeType> {
         Handle {
             node: &mut *self.node as *mut _,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -631,7 +641,8 @@ impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
     pub unsafe fn from_raw<'a>(&'a self) -> Handle<&'a Node<K, V>, Type, NodeType> {
         Handle {
             node: &*self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 
@@ -641,7 +652,8 @@ impl<K, V, Type, NodeType> Handle<*mut Node<K, V>, Type, NodeType> {
     pub unsafe fn from_raw_mut<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, Type, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -689,12 +701,14 @@ impl<K, V, NodeRef: Deref<Target=Node<K, V>>, Type> Handle<NodeRef, Type, handle
         if self.node.is_leaf() {
             Leaf(Handle {
                 node: self.node,
-                index: self.index
+                index: self.index,
+                marker: PhantomData,
             })
         } else {
             Internal(Handle {
                 node: self.node,
-                index: self.index
+                index: self.index,
+                marker: PhantomData,
             })
         }
     }
@@ -827,7 +841,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
     unsafe fn left_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index - 1
+            index: self.index - 1,
+            marker: PhantomData,
         }
     }
 
@@ -837,7 +852,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::Edge, NodeType> where
     unsafe fn right_kv<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::KV, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -877,7 +893,8 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node<K, V>, handle::KV, NodeType
     pub fn into_left_edge(self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 }
@@ -927,7 +944,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
     pub fn left_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index
+            index: self.index,
+            marker: PhantomData,
         }
     }
 
@@ -936,7 +954,8 @@ impl<K, V, NodeRef, NodeType> Handle<NodeRef, handle::KV, NodeType> where
     pub fn right_edge<'a>(&'a mut self) -> Handle<&'a mut Node<K, V>, handle::Edge, NodeType> {
         Handle {
             node: &mut *self.node,
-            index: self.index + 1
+            index: self.index + 1,
+            marker: PhantomData,
         }
     }
 }
@@ -1045,7 +1064,8 @@ impl<K, V> Node<K, V> {
         debug_assert!(index < self.len(), "kv_handle index out of bounds");
         Handle {
             node: self,
-            index: index
+            index: index,
+            marker: PhantomData,
         }
     }
 
@@ -1065,7 +1085,7 @@ impl<K, V> Node<K, V> {
                     vals: RawItems::from_slice(self.vals()),
                     edges: RawItems::from_slice(self.edges()),
 
-                    ptr: self.keys.ptr as *mut u8,
+                    ptr: *self.keys as *mut u8,
                     capacity: self.capacity(),
                     is_leaf: self.is_leaf()
                 },
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index 140c9edb5a3..0c957426060 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -14,6 +14,7 @@
 //! representation to hold C-like enum variants.
 
 use core::prelude::*;
+use core::marker;
 use core::fmt;
 use core::num::Int;
 use core::iter::{FromIterator, IntoIterator};
@@ -26,7 +27,8 @@ use core::ops::{Sub, BitOr, BitAnd, BitXor};
 pub struct EnumSet<E> {
     // We must maintain the invariant that no bits are set
     // for which no variant exists
-    bits: usize
+    bits: usize,
+    marker: marker::PhantomData<E>,
 }
 
 impl<E> Copy for EnumSet<E> {}
@@ -86,7 +88,7 @@ impl<E:CLike> EnumSet<E> {
     #[unstable(feature = "collections",
                reason = "matches collection reform specification, waiting for dust to settle")]
     pub fn new() -> EnumSet<E> {
-        EnumSet {bits: 0}
+        EnumSet {bits: 0, marker: marker::PhantomData}
     }
 
     /// Returns the number of elements in the given `EnumSet`.
@@ -130,12 +132,14 @@ impl<E:CLike> EnumSet<E> {
 
     /// Returns the union of both `EnumSets`.
     pub fn union(&self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits | e.bits}
+        EnumSet {bits: self.bits | e.bits,
+                 marker: marker::PhantomData}
     }
 
     /// Returns the intersection of both `EnumSets`.
     pub fn intersection(&self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & e.bits}
+        EnumSet {bits: self.bits & e.bits,
+                 marker: marker::PhantomData}
     }
 
     /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before
@@ -175,7 +179,7 @@ impl<E:CLike> Sub for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & !e.bits}
+        EnumSet {bits: self.bits & !e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -183,7 +187,7 @@ impl<E:CLike> BitOr for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits | e.bits}
+        EnumSet {bits: self.bits | e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -191,7 +195,7 @@ impl<E:CLike> BitAnd for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits & e.bits}
+        EnumSet {bits: self.bits & e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -199,7 +203,7 @@ impl<E:CLike> BitXor for EnumSet<E> {
     type Output = EnumSet<E>;
 
     fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
-        EnumSet {bits: self.bits ^ e.bits}
+        EnumSet {bits: self.bits ^ e.bits, marker: marker::PhantomData}
     }
 }
 
@@ -207,6 +211,7 @@ impl<E:CLike> BitXor for EnumSet<E> {
 pub struct Iter<E> {
     index: usize,
     bits: usize,
+    marker: marker::PhantomData<E>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -215,13 +220,14 @@ impl<E> Clone for Iter<E> {
         Iter {
             index: self.index,
             bits: self.bits,
+            marker: marker::PhantomData,
         }
     }
 }
 
 impl<E:CLike> Iter<E> {
     fn new(bits: usize) -> Iter<E> {
-        Iter { index: 0, bits: bits }
+        Iter { index: 0, bits: bits, marker: marker::PhantomData }
     }
 }
 
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 1adcb77e0b6..1cc2a5235ab 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -57,13 +57,13 @@ use core::fmt;
 use core::hash::{self, Hash};
 use core::intrinsics::assume;
 use core::iter::{repeat, FromIterator, IntoIterator};
-use core::marker::{self, ContravariantLifetime, InvariantType};
+use core::marker::PhantomData;
 use core::mem;
-use core::nonzero::NonZero;
 use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut, Deref, Add};
 use core::ops;
 use core::ptr;
+use core::ptr::Unique;
 use core::raw::Slice as RawSlice;
 use core::slice;
 use core::usize;
@@ -139,10 +139,9 @@ use borrow::{Cow, IntoCow};
 #[unsafe_no_drop_flag]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Vec<T> {
-    ptr: NonZero<*mut T>,
+    ptr: Unique<T>,
     len: usize,
     cap: usize,
-    _own: marker::PhantomData<T>,
 }
 
 unsafe impl<T: Send> Send for Vec<T> { }
@@ -251,10 +250,9 @@ impl<T> Vec<T> {
     pub unsafe fn from_raw_parts(ptr: *mut T, length: usize,
                                  capacity: usize) -> Vec<T> {
         Vec {
-            ptr: NonZero::new(ptr),
+            ptr: Unique::new(ptr),
             len: length,
             cap: capacity,
-            _own: marker::PhantomData,
         }
     }
 
@@ -375,7 +373,7 @@ impl<T> Vec<T> {
                                      self.len * mem::size_of::<T>(),
                                      mem::min_align_of::<T>()) as *mut T;
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = self.len;
         }
@@ -657,7 +655,7 @@ impl<T> Vec<T> {
             unsafe {
                 let ptr = alloc_or_realloc(*self.ptr, old_size, size);
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = max(self.cap, 2) * 2;
         }
@@ -758,7 +756,7 @@ impl<T> Vec<T> {
             Drain {
                 ptr: begin,
                 end: end,
-                marker: ContravariantLifetime,
+                marker: PhantomData,
             }
         }
     }
@@ -873,6 +871,8 @@ impl<T> Vec<T> {
                 end_t: unsafe { start.offset(offset) },
                 start_u: start as *mut U,
                 end_u: start as *mut U,
+
+                _marker: PhantomData,
             };
             //  start_t
             //  start_u
@@ -969,8 +969,7 @@ impl<T> Vec<T> {
             let mut pv = PartialVecZeroSized::<T,U> {
                 num_t: vec.len(),
                 num_u: 0,
-                marker_t: InvariantType,
-                marker_u: InvariantType,
+                marker: PhantomData,
             };
             unsafe { mem::forget(vec); }
 
@@ -1228,7 +1227,7 @@ impl<T> Vec<T> {
             unsafe {
                 let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::<T>(), size);
                 if ptr.is_null() { ::alloc::oom() }
-                self.ptr = NonZero::new(ptr);
+                self.ptr = Unique::new(ptr);
             }
             self.cap = capacity;
         }
@@ -1795,10 +1794,10 @@ impl<T> Drop for IntoIter<T> {
 #[unsafe_no_drop_flag]
 #[unstable(feature = "collections",
            reason = "recently added as part of collections reform 2")]
-pub struct Drain<'a, T> {
+pub struct Drain<'a, T:'a> {
     ptr: *const T,
     end: *const T,
-    marker: ContravariantLifetime<'a>,
+    marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1883,9 +1882,9 @@ impl<'a, T> Drop for Drain<'a, T> {
 
 /// Wrapper type providing a `&Vec<T>` reference via `Deref`.
 #[unstable(feature = "collections")]
-pub struct DerefVec<'a, T> {
+pub struct DerefVec<'a, T:'a> {
     x: Vec<T>,
-    l: ContravariantLifetime<'a>
+    l: PhantomData<&'a T>,
 }
 
 #[unstable(feature = "collections")]
@@ -1913,7 +1912,7 @@ pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
     unsafe {
         DerefVec {
             x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()),
-            l: ContravariantLifetime::<'a>
+            l: PhantomData,
         }
     }
 }
@@ -1937,6 +1936,8 @@ struct PartialVecNonZeroSized<T,U> {
     end_u: *mut U,
     start_t: *mut T,
     end_t: *mut T,
+
+    _marker: PhantomData<U>,
 }
 
 /// An owned, partially type-converted vector of zero-sized elements.
@@ -1946,8 +1947,7 @@ struct PartialVecNonZeroSized<T,U> {
 struct PartialVecZeroSized<T,U> {
     num_t: usize,
     num_u: usize,
-    marker_t: InvariantType<T>,
-    marker_u: InvariantType<U>,
+    marker: PhantomData<::core::cell::Cell<(T,U)>>,
 }
 
 #[unsafe_destructor]
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 712695841a2..3ba22a41ff7 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -28,7 +28,7 @@ use core::marker;
 use core::mem;
 use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut};
-use core::ptr;
+use core::ptr::{self, Unique};
 use core::raw::Slice as RawSlice;
 
 use core::hash::{Hash, Hasher};
@@ -57,7 +57,7 @@ pub struct VecDeque<T> {
     tail: usize,
     head: usize,
     cap: usize,
-    ptr: *mut T
+    ptr: Unique<T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -80,7 +80,7 @@ impl<T> Drop for VecDeque<T> {
         self.clear();
         unsafe {
             if mem::size_of::<T>() != 0 {
-                heap::deallocate(self.ptr as *mut u8,
+                heap::deallocate(*self.ptr as *mut u8,
                                  self.cap * mem::size_of::<T>(),
                                  mem::min_align_of::<T>())
             }
@@ -98,13 +98,13 @@ impl<T> VecDeque<T> {
     /// Turn ptr into a slice
     #[inline]
     unsafe fn buffer_as_slice(&self) -> &[T] {
-        mem::transmute(RawSlice { data: self.ptr, len: self.cap })
+        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
     }
 
     /// Turn ptr into a mut slice
     #[inline]
     unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
-        mem::transmute(RawSlice { data: self.ptr, len: self.cap })
+        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
     }
 
     /// Moves an element out of the buffer
@@ -171,21 +171,21 @@ impl<T> VecDeque<T> {
         let size = cap.checked_mul(mem::size_of::<T>())
                       .expect("capacity overflow");
 
-        let ptr = if mem::size_of::<T>() != 0 {
-            unsafe {
+        let ptr = unsafe {
+            if mem::size_of::<T>() != 0 {
                 let ptr = heap::allocate(size, mem::min_align_of::<T>())  as *mut T;;
                 if ptr.is_null() { ::alloc::oom() }
-                ptr
+                Unique::new(ptr)
+            } else {
+                Unique::new(heap::EMPTY as *mut T)
             }
-        } else {
-            heap::EMPTY as *mut T
         };
 
         VecDeque {
             tail: 0,
             head: 0,
             cap: cap,
-            ptr: ptr
+            ptr: ptr,
         }
     }
 
@@ -341,11 +341,12 @@ impl<T> VecDeque<T> {
                 let new = count.checked_mul(mem::size_of::<T>())
                                .expect("capacity overflow");
                 unsafe {
-                    self.ptr = heap::reallocate(self.ptr as *mut u8,
-                                                old,
-                                                new,
-                                                mem::min_align_of::<T>()) as *mut T;
-                    if self.ptr.is_null() { ::alloc::oom() }
+                    let ptr = heap::reallocate(*self.ptr as *mut u8,
+                                               old,
+                                               new,
+                                               mem::min_align_of::<T>()) as *mut T;
+                    if ptr.is_null() { ::alloc::oom() }
+                    self.ptr = Unique::new(ptr);
                 }
             }
 
@@ -459,11 +460,12 @@ impl<T> VecDeque<T> {
                 let old = self.cap * mem::size_of::<T>();
                 let new_size = target_cap * mem::size_of::<T>();
                 unsafe {
-                    self.ptr = heap::reallocate(self.ptr as *mut u8,
-                                                old,
-                                                new_size,
-                                                mem::min_align_of::<T>()) as *mut T;
-                    if self.ptr.is_null() { ::alloc::oom() }
+                    let ptr = heap::reallocate(*self.ptr as *mut u8,
+                                               old,
+                                               new_size,
+                                               mem::min_align_of::<T>()) as *mut T;
+                    if ptr.is_null() { ::alloc::oom() }
+                    self.ptr = Unique::new(ptr);
                 }
             }
             self.cap = target_cap;
@@ -545,8 +547,8 @@ impl<T> VecDeque<T> {
             tail: self.tail,
             head: self.head,
             cap: self.cap,
-            ptr: self.ptr,
-            marker: marker::ContravariantLifetime,
+            ptr: *self.ptr,
+            marker: marker::PhantomData,
         }
     }
 
@@ -1342,7 +1344,7 @@ impl<T> VecDeque<T> {
                 // `at` lies in the first half.
                 let amount_in_first = first_len - at;
 
-                ptr::copy_nonoverlapping_memory(other.ptr,
+                ptr::copy_nonoverlapping_memory(*other.ptr,
                                                 first_half.as_ptr().offset(at as isize),
                                                 amount_in_first);
 
@@ -1355,7 +1357,7 @@ impl<T> VecDeque<T> {
                 // in the first half.
                 let offset = at - first_len;
                 let amount_in_second = second_len - offset;
-                ptr::copy_nonoverlapping_memory(other.ptr,
+                ptr::copy_nonoverlapping_memory(*other.ptr,
                                                 second_half.as_ptr().offset(offset as isize),
                                                 amount_in_second);
             }
@@ -1524,7 +1526,7 @@ pub struct IterMut<'a, T:'a> {
     tail: usize,
     head: usize,
     cap: usize,
-    marker: marker::ContravariantLifetime<'a>,
+    marker: marker::PhantomData<&'a mut T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2004,9 +2006,9 @@ mod tests {
 
     #[derive(Clone, PartialEq, Debug)]
     enum Taggypar<T> {
-        Onepar(i32),
-        Twopar(i32, i32),
-        Threepar(i32, i32, i32),
+        Onepar(T),
+        Twopar(T, T),
+        Threepar(T, T, T),
     }
 
     #[derive(Clone, PartialEq, Debug)]
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 9f0489a4f96..54589a31423 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -876,7 +876,7 @@ pub struct IntoIter<V> {
 }
 
 #[unstable(feature = "collections")]
-pub struct Drain<'a, V> {
+pub struct Drain<'a, V:'a> {
     iter: FilterMap<
     Enumerate<vec::Drain<'a, Option<V>>>,
     fn((usize, Option<V>)) -> Option<(usize, V)>>
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index 05d864accc1..6afe5b2257d 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -76,6 +76,7 @@ use marker::Sync;
 
 use intrinsics;
 use cell::UnsafeCell;
+use marker::PhantomData;
 
 /// A boolean type which can be safely shared between threads.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -105,6 +106,7 @@ unsafe impl Sync for AtomicUsize {}
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct AtomicPtr<T> {
     p: UnsafeCell<usize>,
+    _marker: PhantomData<*mut T>,
 }
 
 unsafe impl<T> Sync for AtomicPtr<T> {}
@@ -791,7 +793,8 @@ impl<T> AtomicPtr<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(p: *mut T) -> AtomicPtr<T> {
-        AtomicPtr { p: UnsafeCell::new(p as usize) }
+        AtomicPtr { p: UnsafeCell::new(p as usize),
+                    _marker: PhantomData }
     }
 
     /// Loads a value from the pointer.
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 67c8c9fec09..a2c1bbc0331 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -16,7 +16,7 @@ use any;
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
 use char::CharExt;
 use iter::{Iterator, IteratorExt};
-use marker::{Copy, Sized};
+use marker::{Copy, PhantomData, Sized};
 use mem;
 use option::Option;
 use option::Option::{Some, None};
@@ -914,6 +914,11 @@ impl Debug for () {
         f.pad("()")
     }
 }
+impl<T> Debug for PhantomData<T> {
+    fn fmt(&self, f: &mut Formatter) -> Result {
+        f.pad("PhantomData")
+    }
+}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Copy + Debug> Debug for Cell<T> {
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 194c0dc4f28..8fb10b5b2dc 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -62,6 +62,7 @@ use clone::Clone;
 use cmp;
 use cmp::Ord;
 use default::Default;
+use marker;
 use mem;
 use num::{ToPrimitive, Int};
 use ops::{Add, Deref, FnMut};
@@ -947,7 +948,7 @@ pub trait IteratorExt: Iterator + Sized {
         FromB: Default + Extend<B>,
         Self: Iterator<Item=(A, B)>,
     {
-        struct SizeHint<A>(usize, Option<usize>);
+        struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>);
         impl<A> Iterator for SizeHint<A> {
             type Item = A;
 
@@ -961,8 +962,8 @@ pub trait IteratorExt: Iterator + Sized {
         let mut ts: FromA = Default::default();
         let mut us: FromB = Default::default();
 
-        ts.extend(SizeHint(lo, hi));
-        us.extend(SizeHint(lo, hi));
+        ts.extend(SizeHint(lo, hi, marker::PhantomData));
+        us.extend(SizeHint(lo, hi, marker::PhantomData));
 
         for (t, u) in self {
             ts.extend(Some(t).into_iter());
@@ -2064,8 +2065,8 @@ pub struct Scan<I, St, F> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<B, I: Iterator, St, F> Iterator for Scan<I, St, F> where
-    F: FnMut(&mut St, I::Item) -> Option<B>,
+impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where
+    F: FnMut(&mut St, A) -> Option<B>,
 {
     type Item = B;
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 56e1c5dedc1..dc792a3f47f 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -26,6 +26,10 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use clone::Clone;
+use cmp;
+use option::Option;
+use hash::Hash;
+use hash::Hasher;
 
 /// Types able to be transferred across thread boundaries.
 #[unstable(feature = "core",
@@ -37,12 +41,11 @@ pub unsafe trait Send: 'static {
     // empty.
 }
 /// Types able to be transferred across thread boundaries.
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[lang="send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
 #[cfg(not(stage0))]
-pub unsafe trait Send {
+pub unsafe trait Send : MarkerTrait {
     // empty.
 }
 
@@ -50,7 +53,7 @@ pub unsafe trait Send {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sized"]
 #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"]
-pub trait Sized {
+pub trait Sized : MarkerTrait {
     // Empty.
 }
 
@@ -155,7 +158,7 @@ pub trait Sized {
 /// change: that second example would fail to compile if we made `Foo` non-`Copy`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang="copy"]
-pub trait Copy {
+pub trait Copy : MarkerTrait {
     // Empty.
 }
 
@@ -204,236 +207,172 @@ pub trait Copy {
 /// around the value(s) which can be mutated when behind a `&`
 /// reference; not doing this is undefined behaviour (for example,
 /// `transmute`-ing from `&T` to `&mut T` is illegal).
-#[unstable(feature = "core",
-           reason = "will be overhauled with new lifetime rules; see RFC 458")]
+#[stable(feature = "rust1", since = "1.0.0")]
 #[lang="sync"]
 #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
-pub unsafe trait Sync {
+pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
 
-/// A marker type that indicates to the compiler that the instances
-/// of the type itself owns instances of the type parameter `T`.
-///
-/// This is used to indicate that one or more instances of the type
-/// `T` could be dropped when instances of the type itself is dropped,
-/// though that may not be apparent from the other structure of the
-/// type itself. For example, the type may hold a `*mut T`, which the
-/// compiler does not automatically treat as owned.
+/// A type which is considered "not POD", meaning that it is not
+/// implicitly copyable. This is typically embedded in other types to
+/// ensure that they are never copied, even if they lack a destructor.
 #[unstable(feature = "core",
-           reason = "Newly added to deal with scoping and destructor changes")]
-#[lang="phantom_data"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct PhantomData<T: ?Sized>;
+           reason = "likely to change with new variance strategy")]
+#[lang="no_copy_bound"]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct NoCopy;
 
-impl<T: ?Sized> Copy for PhantomData<T> {}
-impl<T: ?Sized> Clone for PhantomData<T> {
-    fn clone(&self) -> PhantomData<T> { *self }
+/// A type which is considered managed by the GC. This is typically
+/// embedded in other types.
+#[unstable(feature = "core",
+           reason = "likely to change with new variance strategy")]
+#[lang="managed_bound"]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Managed;
+
+macro_rules! impls{
+    ($t: ident) => (
+        impl<T:?Sized, S: Hasher> Hash<S> for $t<T> {
+            #[inline]
+            fn hash(&self, _: &mut S) {
+            }
+        }
+
+        impl<T:?Sized> cmp::PartialEq for $t<T> {
+            fn eq(&self, _other: &$t<T>) -> bool {
+                true
+            }
+        }
+
+        impl<T:?Sized> cmp::Eq for $t<T> {
+        }
+
+        impl<T:?Sized> cmp::PartialOrd for $t<T> {
+            fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> {
+                Option::Some(cmp::Ordering::Equal)
+            }
+        }
+
+        impl<T:?Sized> cmp::Ord for $t<T> {
+            fn cmp(&self, _other: &$t<T>) -> cmp::Ordering {
+                cmp::Ordering::Equal
+            }
+        }
+
+        impl<T:?Sized> Copy for $t<T> { }
+
+        impl<T:?Sized> Clone for $t<T> {
+            fn clone(&self) -> $t<T> {
+                $t
+            }
+        }
+        )
 }
 
-/// A marker type whose type parameter `T` is considered to be
-/// covariant with respect to the type itself. This is (typically)
-/// used to indicate that an instance of the type `T` is being stored
-/// into memory and read from, even though that may not be apparent.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-///
-/// *Note:* It is very unusual to have to add a covariant constraint.
-/// If you are not sure, you probably want to use `InvariantType`.
+/// `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!
+pub trait MarkerTrait : PhantomFn<Self> { }
+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>`.
 ///
 /// # Example
 ///
-/// Given a struct `S` that includes a type parameter `T`
-/// but does not actually *reference* that type parameter:
+/// As an example, consider a trait with no methods like `Even`, meant
+/// to represent types that are "even":
 ///
-/// ```ignore
-/// use std::mem;
-///
-/// struct S<T> { x: *() }
-/// fn get<T>(s: &S<T>) -> T {
-///    unsafe {
-///        let x: *T = mem::transmute(s.x);
-///        *x
-///    }
-/// }
+/// ```rust
+/// trait Even { }
 /// ```
 ///
-/// The type system would currently infer that the value of
-/// the type parameter `T` is irrelevant, and hence a `S<int>` is
-/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
-/// any `U`). But this is incorrect because `get()` converts the
-/// `*()` into a `*T` and reads from it. Therefore, we should include the
-/// a marker field `CovariantType<T>` to inform the type checker that
-/// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
-/// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
-/// for some lifetime `'a`, but not the other way around).
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="covariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct CovariantType<T: ?Sized>;
-
-impl<T: ?Sized> Copy for CovariantType<T> {}
-impl<T: ?Sized> Clone for CovariantType<T> {
-    fn clone(&self) -> CovariantType<T> { *self }
-}
-
-/// A marker type whose type parameter `T` is considered to be
-/// contravariant with respect to the type itself. This is (typically)
-/// used to indicate that an instance of the type `T` will be consumed
-/// (but not read from), even though that may not be apparent.
+/// 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:
 ///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
+/// ```rust
+/// trait Even {
+///     fn is_even(self) -> bool { true }
+/// }
+/// ```
 ///
-/// *Note:* It is very unusual to have to add a contravariant constraint.
-/// If you are not sure, you probably want to use `InvariantType`.
+/// Therefore, we can model a method like this as follows:
 ///
-/// # Example
+/// ```rust
+/// use std::marker::PhantomFn
+/// trait Even : PhantomFn<Self> { }
+/// ```
 ///
-/// Given a struct `S` that includes a type parameter `T`
-/// but does not actually *reference* that type parameter:
+/// Another equivalent, but clearer, option would be to use
+/// `MarkerTrait`:
 ///
+/// ```rust
+/// use std::marker::MarkerTrait;
+/// trait Even : MarkerTrait { }
 /// ```
-/// use std::mem;
-///
-/// struct S<T> { x: *const () }
-/// fn get<T>(s: &S<T>, v: T) {
-///    unsafe {
-///        let x: fn(T) = mem::transmute(s.x);
-///        x(v)
-///    }
-/// }
-/// ```
-///
-/// The type system would currently infer that the value of
-/// the type parameter `T` is irrelevant, and hence a `S<int>` is
-/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
-/// any `U`). But this is incorrect because `get()` converts the
-/// `*()` into a `fn(T)` and then passes a value of type `T` to it.
-///
-/// Supplying a `ContravariantType` marker would correct the
-/// problem, because it would mark `S` so that `S<T>` is only a
-/// subtype of `S<U>` if `U` is a subtype of `T`; given that the
-/// function requires arguments of type `T`, it must also accept
-/// arguments of type `U`, hence such a conversion is safe.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="contravariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct ContravariantType<T: ?Sized>;
-
-impl<T: ?Sized> Copy for ContravariantType<T> {}
-impl<T: ?Sized> Clone for ContravariantType<T> {
-    fn clone(&self) -> ContravariantType<T> { *self }
-}
-
-/// A marker type whose type parameter `T` is considered to be
-/// invariant with respect to the type itself. This is (typically)
-/// used to indicate that instances of the type `T` may be read or
-/// written, even though that may not be apparent.
 ///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
+/// # Parameters
 ///
-/// # Example
+/// - `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.
 ///
-/// The Cell type is an example of an `InvariantType` which uses unsafe
-/// code to achieve "interior" mutability:
+/// # Additional reading
 ///
-/// ```
-/// struct Cell<T> { value: T }
-/// ```
+/// More details and background can be found in [RFC 738][738].
 ///
-/// The type system would infer that `value` is only read here
-/// and never written, but in fact `Cell` uses unsafe code to achieve
-/// interior mutability. In order to get correct behavior, the
-/// `InvariantType` marker must be applied.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="invariant_type"]
-#[derive(PartialEq, Eq, PartialOrd, Ord)]
-pub struct InvariantType<T: ?Sized>;
-
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-impl<T: ?Sized> Copy for InvariantType<T> {}
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-impl<T: ?Sized> Clone for InvariantType<T> {
-    fn clone(&self) -> InvariantType<T> { *self }
-}
-
-/// As `CovariantType`, but for lifetime parameters. Using
-/// `CovariantLifetime<'a>` indicates that it is ok to substitute
-/// a *longer* lifetime for `'a` than the one you originally
-/// started with (e.g., you could convert any lifetime `'foo` to
-/// `'static`). You almost certainly want `ContravariantLifetime`
-/// instead, or possibly `InvariantLifetime`. The only case where
-/// it would be appropriate is that you have a (type-casted, and
-/// hence hidden from the type system) function pointer with a
-/// signature like `fn(&'a T)` (and no other uses of `'a`). In
-/// this case, it is ok to substitute a larger lifetime for `'a`
-/// (e.g., `fn(&'static T)`), because the function is only
-/// becoming more selective in terms of what it accepts as
-/// argument.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="covariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct CovariantLifetime<'a>;
+/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
+#[lang="phantom_fn"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait PhantomFn<A:?Sized,R:?Sized=()> { }
 
-/// As `ContravariantType`, but for lifetime parameters. Using
-/// `ContravariantLifetime<'a>` indicates that it is ok to
-/// substitute a *shorter* lifetime for `'a` than the one you
-/// originally started with (e.g., you could convert `'static` to
-/// any lifetime `'foo`). This is appropriate for cases where you
-/// have an unsafe pointer that is actually a pointer into some
-/// memory with lifetime `'a`, and thus you want to limit the
-/// lifetime of your data structure to `'a`. An example of where
-/// this is used is the iterator for vectors.
-///
-/// For more information about variance, refer to this Wikipedia
-/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="contravariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct ContravariantLifetime<'a>;
+#[cfg(stage0)] // built into the trait matching system after stage0
+impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { }
 
-/// As `InvariantType`, but for lifetime parameters. Using
-/// `InvariantLifetime<'a>` indicates that it is not ok to
-/// substitute any other lifetime for `'a` besides its original
-/// value. This is appropriate for cases where you have an unsafe
-/// pointer that is actually a pointer into memory with lifetime `'a`,
-/// and this pointer is itself stored in an inherently mutable
-/// location (such as a `Cell`).
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="invariant_lifetime"]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct InvariantLifetime<'a>;
+/// Specific to stage0. You should not be seeing these docs!
+#[cfg(stage0)]
+#[lang="covariant_type"] // only relevant to stage0
+pub struct PhantomData<T:?Sized>;
 
-/// A type which is considered "not POD", meaning that it is not
-/// implicitly copyable. This is typically embedded in other types to
-/// ensure that they are never copied, even if they lack a destructor.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="no_copy_bound"]
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct NoCopy;
+/// `PhantomData` is a way to tell the compiler about fake fields.
+/// Phantom data is required whenever type parameters are not used.
+/// The idea is that if the compiler encounters a `PhantomData<T>`
+/// instance, it will behave *as if* an instance of the type `T` were
+/// present for the purpose of various automatic analyses.
+///
+/// For example, embedding a `PhantomData<T>` will inform the compiler
+/// that one or more instances of the type `T` could be dropped when
+/// instances of the type itself is dropped, though that may not be
+/// apparent from the other structure of the type itself. This is
+/// commonly necessary if the structure is using an unsafe pointer
+/// like `*mut T` whose referent may be dropped when the type is
+/// dropped, as a `*mut T` is otherwise not treated as owned.
+///
+/// FIXME. Better documentation and examples of common patterns needed
+/// here! For now, please see [RFC 738][738] for more information.
+///
+/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md
+#[cfg(not(stage0))]
+#[lang="phantom_data"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct PhantomData<T:?Sized>;
 
-/// A type which is considered managed by the GC. This is typically
-/// embedded in other types.
-#[unstable(feature = "core",
-           reason = "likely to change with new variance strategy")]
-#[lang="managed_bound"]
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Managed;
+impls! { PhantomData }
 
 #[cfg(not(stage0))]
 mod impls {
@@ -442,3 +381,40 @@ mod impls {
     unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {}
     unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {}
 }
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")]
+#[lang="contravariant_lifetime"]
+pub struct ContravariantLifetime<'a>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(&'a ())>`")]
+#[lang="covariant_lifetime"]
+pub struct CovariantLifetime<'a>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<&'a ()>>`")]
+#[lang="invariant_lifetime"]
+pub struct InvariantLifetime<'a>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(T)>`")]
+#[lang="contravariant_type"]
+pub struct ContravariantType<T>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<T>`")]
+#[lang="covariant_type"]
+#[cfg(not(stage0))]
+pub struct CovariantType<T>;
+
+/// Old-style marker trait. Deprecated.
+#[unstable(feature = "core", reason = "deprecated")]
+#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<T>>`")]
+#[lang="invariant_type"]
+pub struct InvariantType<T>;
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 5644f763069..230587b726f 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -10,15 +10,14 @@
 
 //! Exposes the NonZero lang item which provides optimization hints.
 
+use marker::{Sized, MarkerTrait};
 use ops::Deref;
-use ptr::Unique;
 
 /// Unsafe trait to indicate what types are usable with the NonZero struct
-pub unsafe trait Zeroable {}
+pub unsafe trait Zeroable : MarkerTrait {}
 
-unsafe impl<T> Zeroable for *const T {}
-unsafe impl<T> Zeroable for *mut T {}
-unsafe impl<T> Zeroable for Unique<T> { }
+unsafe impl<T:?Sized> Zeroable for *const T {}
+unsafe impl<T:?Sized> Zeroable for *mut T {}
 unsafe impl Zeroable for isize {}
 unsafe impl Zeroable for usize {}
 unsafe impl Zeroable for i8 {}
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 2779e67c743..16b84dcf18e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -91,8 +91,10 @@
 use mem;
 use clone::Clone;
 use intrinsics;
+use ops::Deref;
 use option::Option::{self, Some, None};
-use marker::{self, Send, Sized, Sync};
+use marker::{PhantomData, Send, Sized, Sync};
+use nonzero::NonZero;
 
 use cmp::{PartialEq, Eq, Ord, PartialOrd};
 use cmp::Ordering::{self, Less, Equal, Greater};
@@ -517,15 +519,16 @@ impl<T> PartialOrd for *mut T {
 
 /// A wrapper around a raw `*mut T` that indicates that the possessor
 /// of this wrapper owns the referent. This in turn implies that the
-/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a
-/// raw `*mut T` (which conveys no particular ownership semantics).
-/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which
+/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw
+/// `*mut T` (which conveys no particular ownership semantics).  It
+/// also implies that the referent of the pointer should not be
+/// modified without a unique path to the `Unique` reference. Useful
+/// for building abstractions like `Vec<T>` or `Box<T>`, which
 /// internally use raw pointers to manage the memory that they own.
 #[unstable(feature = "core", reason = "recently added to this module")]
-pub struct Unique<T: ?Sized> {
-    /// The wrapped `*mut T`.
-    pub ptr: *mut T,
-    _own: marker::PhantomData<T>,
+pub struct Unique<T:?Sized> {
+    pointer: NonZero<*const T>,
+    _marker: PhantomData<T>,
 }
 
 /// `Unique` pointers are `Send` if `T` is `Send` because the data they
@@ -542,25 +545,34 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
 #[unstable(feature = "core", reason = "recently added to this module")]
 unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
 
-impl<T> Unique<T> {
-    /// Returns a null Unique.
+impl<T:?Sized> Unique<T> {
+    /// Create a new `Unique`.
     #[unstable(feature = "core",
                reason = "recently added to this module")]
-    pub fn null() -> Unique<T> {
-        Unique(null_mut())
+    pub unsafe fn new(ptr: *mut T) -> Unique<T> {
+        Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
     }
 
-    /// Return an (unsafe) pointer into the memory owned by `self`.
+    /// Dereference the content.
     #[unstable(feature = "core",
                reason = "recently added to this module")]
-    pub unsafe fn offset(self, offset: isize) -> *mut T {
-        self.ptr.offset(offset)
+    pub unsafe fn get(&self) -> &T {
+        &**self.pointer
+    }
+
+    /// Mutably dereference the content.
+    #[unstable(feature = "core",
+               reason = "recently added to this module")]
+    pub unsafe fn get_mut(&mut self) -> &mut T {
+        &mut ***self
     }
 }
 
-/// Creates a `Unique` wrapped around `ptr`, taking ownership of the
-/// data referenced by `ptr`.
-#[allow(non_snake_case)]
-pub fn Unique<T: ?Sized>(ptr: *mut T) -> Unique<T> {
-    Unique { ptr: ptr, _own: marker::PhantomData }
+impl<T:?Sized> Deref for Unique<T> {
+    type Target = *mut T;
+
+    #[inline]
+    fn deref<'a>(&'a self) -> &'a *mut T {
+        unsafe { mem::transmute(&*self.pointer) }
+    }
 }
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index bbfe7e58ef4..a86da53b372 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -140,11 +140,11 @@ impl<T> SliceExt for [T] {
             if mem::size_of::<T>() == 0 {
                 Iter {ptr: p,
                       end: (p as usize + self.len()) as *const T,
-                      marker: marker::ContravariantLifetime::<'a>}
+                      _marker: marker::PhantomData}
             } else {
                 Iter {ptr: p,
                       end: p.offset(self.len() as isize),
-                      marker: marker::ContravariantLifetime::<'a>}
+                      _marker: marker::PhantomData}
             }
         }
     }
@@ -279,11 +279,11 @@ impl<T> SliceExt for [T] {
             if mem::size_of::<T>() == 0 {
                 IterMut {ptr: p,
                          end: (p as usize + self.len()) as *mut T,
-                         marker: marker::ContravariantLifetime::<'a>}
+                         _marker: marker::PhantomData}
             } else {
                 IterMut {ptr: p,
                          end: p.offset(self.len() as isize),
-                         marker: marker::ContravariantLifetime::<'a>}
+                         _marker: marker::PhantomData}
             }
         }
     }
@@ -733,7 +733,7 @@ macro_rules! make_slice {
 pub struct Iter<'a, T: 'a> {
     ptr: *const T,
     end: *const T,
-    marker: marker::ContravariantLifetime<'a>
+    _marker: marker::PhantomData<&'a T>,
 }
 
 #[unstable(feature = "core")]
@@ -790,7 +790,7 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Iter<'a, T> {
-    fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, marker: self.marker } }
+    fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
@@ -823,7 +823,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> {
 pub struct IterMut<'a, T: 'a> {
     ptr: *mut T,
     end: *mut T,
-    marker: marker::ContravariantLifetime<'a>,
+    _marker: marker::PhantomData<&'a mut T>,
 }
 
 
diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs
index 421ce76caaf..5aeb330b78b 100644
--- a/src/libcoretest/mem.rs
+++ b/src/libcoretest/mem.rs
@@ -92,7 +92,7 @@ fn test_transmute_copy() {
 
 #[test]
 fn test_transmute() {
-    trait Foo {}
+    trait Foo { fn dummy(&self) { } }
     impl Foo for int {}
 
     let a = box 100 as Box<Foo>;
diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs
index 9c2e242c105..57456bfb1a7 100644
--- a/src/libcoretest/ptr.rs
+++ b/src/libcoretest/ptr.rs
@@ -171,8 +171,8 @@ fn test_set_memory() {
 #[test]
 fn test_unsized_unique() {
     let xs: &mut [_] = &mut [1, 2, 3];
-    let ptr = Unique(xs as *mut [_]);
-    let ys = unsafe { &mut *ptr.ptr };
+    let ptr = unsafe { Unique::new(xs as *mut [_]) };
+    let ys = unsafe { &mut **ptr };
     let zs: &mut [_] = &mut [1, 2, 3];
     assert!(ys == zs);
 }
diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs
index ff6400a11df..24660b3f396 100644
--- a/src/libflate/lib.rs
+++ b/src/libflate/lib.rs
@@ -45,13 +45,13 @@ pub struct Bytes {
 impl Deref for Bytes {
     type Target = [u8];
     fn deref(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts_mut(self.ptr.ptr, self.len) }
+        unsafe { slice::from_raw_parts(*self.ptr, self.len) }
     }
 }
 
 impl Drop for Bytes {
     fn drop(&mut self) {
-        unsafe { libc::free(self.ptr.ptr as *mut _); }
+        unsafe { libc::free(*self.ptr as *mut _); }
     }
 }
 
@@ -84,7 +84,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
                                              &mut outsz,
                                              flags);
         if !res.is_null() {
-            let res = Unique(res as *mut u8);
+            let res = Unique::new(res as *mut u8);
             Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
@@ -110,7 +110,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
                                                &mut outsz,
                                                flags);
         if !res.is_null() {
-            let res = Unique(res as *mut u8);
+            let res = Unique::new(res as *mut u8);
             Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index d1d24cea871..5a85552dc38 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -21,6 +21,7 @@
 
 use core::prelude::*;
 use core::num::{Float, Int};
+use core::marker::PhantomData;
 
 use {Rng, Rand};
 
@@ -56,7 +57,13 @@ pub trait IndependentSample<Support>: Sample<Support> {
 
 /// A wrapper for generating types that implement `Rand` via the
 /// `Sample` & `IndependentSample` traits.
-pub struct RandSample<Sup>;
+pub struct RandSample<Sup> { _marker: PhantomData<Sup> }
+
+impl<Sup> RandSample<Sup> {
+    pub fn new() -> RandSample<Sup> {
+        RandSample { _marker: PhantomData }
+    }
+}
 
 impl<Sup: Rand> Sample<Sup> for RandSample<Sup> {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup { self.ind_sample(rng) }
@@ -285,7 +292,7 @@ mod tests {
 
     #[test]
     fn test_rand_sample() {
-        let mut rand_sample = RandSample::<ConstRand>;
+        let mut rand_sample = RandSample::<ConstRand>::new();
 
         assert_eq!(rand_sample.sample(&mut ::test::rng()), ConstRand(0));
         assert_eq!(rand_sample.ind_sample(&mut ::test::rng()), ConstRand(0));
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 915c70bbf8c..7588bf7c515 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -41,6 +41,7 @@ extern crate core;
 #[cfg(test)] #[macro_use] extern crate log;
 
 use core::prelude::*;
+use core::marker::PhantomData;
 
 pub use isaac::{IsaacRng, Isaac64Rng};
 pub use chacha::ChaChaRng;
@@ -206,7 +207,7 @@ pub trait Rng : Sized {
     ///                     .collect::<Vec<(f64, bool)>>());
     /// ```
     fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
-        Generator { rng: self }
+        Generator { rng: self, _marker: PhantomData }
     }
 
     /// Generate a random value in the range [`low`, `high`).
@@ -317,6 +318,7 @@ pub trait Rng : Sized {
 /// This iterator is created via the `gen_iter` method on `Rng`.
 pub struct Generator<'a, T, R:'a> {
     rng: &'a mut R,
+    _marker: PhantomData<T>
 }
 
 impl<'a, T: Rand, R: Rng> Iterator for Generator<'a, T, R> {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 147fc5ea7f9..e99d214742a 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -29,7 +29,6 @@ use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
 use middle::ty::{MethodStatic, MethodStaticClosure};
 use util::ppaux::Repr;
 
-use std::marker;
 use syntax::{ast, ast_util};
 use syntax::ptr::P;
 use syntax::codemap::Span;
@@ -128,16 +127,14 @@ pub enum MatchMode {
     MovingMatch,
 }
 
-#[derive(PartialEq,Debug)]
-enum TrackMatchMode<T> {
+#[derive(Copy, PartialEq, Debug)]
+enum TrackMatchMode {
     Unknown,
     Definite(MatchMode),
     Conflicting,
 }
 
-impl<T> marker::Copy for TrackMatchMode<T> {}
-
-impl<T> TrackMatchMode<T> {
+impl TrackMatchMode {
     // Builds up the whole match mode for a pattern from its constituent
     // parts.  The lattice looks like this:
     //
@@ -931,7 +928,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
         return true;
     }
 
-    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode<Span> {
+    fn arm_move_mode(&mut self, discr_cmt: mc::cmt<'tcx>, arm: &ast::Arm) -> TrackMatchMode {
         let mut mode = Unknown;
         for pat in &arm.pats {
             self.determine_pat_move_mode(discr_cmt.clone(), &**pat, &mut mode);
@@ -966,7 +963,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     fn determine_pat_move_mode(&mut self,
                                cmt_discr: mc::cmt<'tcx>,
                                pat: &ast::Pat,
-                               mode: &mut TrackMatchMode<Span>) {
+                               mode: &mut TrackMatchMode) {
         debug!("determine_pat_move_mode cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
                pat.repr(self.tcx()));
         return_if_err!(self.mc.cat_pattern(cmt_discr, pat, |_mc, cmt_pat, pat| {
diff --git a/src/librustc/middle/infer/bivariate.rs b/src/librustc/middle/infer/bivariate.rs
new file mode 100644
index 00000000000..93c80fb754f
--- /dev/null
+++ b/src/librustc/middle/infer/bivariate.rs
@@ -0,0 +1,145 @@
+// 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 <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.
+
+//! Applies the "bivariance relationship" to two types and/or regions.
+//! If (A,B) are bivariant then either A <: B or B <: A. It occurs
+//! when type/lifetime parameters are unconstrained. Usually this is
+//! an error, but we permit it in the specific case where a type
+//! parameter is constrained in a where-clause via an associated type.
+//!
+//! There are several ways one could implement bivariance. You could
+//! just do nothing at all, for example, or you could fully verify
+//! that one of the two subtyping relationships hold. We choose to
+//! thread a middle line: we relate types up to regions, but ignore
+//! all region relationships.
+//!
+//! At one point, handling bivariance in this fashion was necessary
+//! for inference, but I'm actually not sure if that is true anymore.
+//! In particular, it might be enough to say (A,B) are bivariant for
+//! all (A,B).
+
+use middle::ty::{BuiltinBounds};
+use middle::ty::{self, Ty};
+use middle::ty::TyVar;
+use middle::infer::combine::*;
+use middle::infer::{cres};
+use middle::infer::type_variable::{BiTo};
+use util::ppaux::{Repr};
+
+use syntax::ast::{Unsafety};
+
+pub struct Bivariate<'f, 'tcx: 'f> {
+    fields: CombineFields<'f, 'tcx>
+}
+
+#[allow(non_snake_case)]
+pub fn Bivariate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Bivariate<'f, 'tcx> {
+    Bivariate { fields: cf }
+}
+
+impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
+    fn tag(&self) -> String { "Bivariate".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
+
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Contravariant => self.tys(a, b),
+            ty::Bivariant => self.tys(a, b),
+        }
+    }
+
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Contravariant => self.regions(a, b),
+            ty::Bivariant => self.regions(a, b),
+        }
+    }
+
+    fn regions(&self, a: ty::Region, _: ty::Region) -> cres<'tcx, ty::Region> {
+        Ok(a)
+    }
+
+    fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
+        debug!("mts({} <: {})",
+               a.repr(self.fields.infcx.tcx),
+               b.repr(self.fields.infcx.tcx));
+
+        if a.mutbl != b.mutbl { return Err(ty::terr_mutability); }
+        let t = try!(self.tys(a.ty, b.ty));
+        Ok(ty::mt { mutbl: a.mutbl, ty: t })
+    }
+
+    fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
+        if a != b {
+            Err(ty::terr_unsafety_mismatch(expected_found(self, a, b)))
+        } else {
+            Ok(a)
+        }
+    }
+
+    fn builtin_bounds(&self,
+                      a: BuiltinBounds,
+                      b: BuiltinBounds)
+                      -> cres<'tcx, BuiltinBounds>
+    {
+        if a != b {
+            Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
+        } else {
+            Ok(a)
+        }
+    }
+
+    fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+        debug!("{}.tys({}, {})", self.tag(),
+               a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx));
+        if a == b { return Ok(a); }
+
+        let infcx = self.fields.infcx;
+        let a = infcx.type_variables.borrow().replace_if_possible(a);
+        let b = infcx.type_variables.borrow().replace_if_possible(b);
+        match (&a.sty, &b.sty) {
+            (&ty::ty_infer(TyVar(a_id)), &ty::ty_infer(TyVar(b_id))) => {
+                infcx.type_variables.borrow_mut().relate_vars(a_id, BiTo, b_id);
+                Ok(a)
+            }
+
+            (&ty::ty_infer(TyVar(a_id)), _) => {
+                try!(self.fields.instantiate(b, BiTo, a_id));
+                Ok(a)
+            }
+
+            (_, &ty::ty_infer(TyVar(b_id))) => {
+                try!(self.fields.instantiate(a, BiTo, b_id));
+                Ok(a)
+            }
+
+            _ => {
+                super_tys(self, a, b)
+            }
+        }
+    }
+
+    fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
+        where T : Combineable<'tcx>
+    {
+        let a1 = ty::erase_late_bound_regions(self.tcx(), a);
+        let b1 = ty::erase_late_bound_regions(self.tcx(), b);
+        let c = try!(Combineable::combine(self, &a1, &b1));
+        Ok(ty::Binder(c))
+    }
+}
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index 70b444d81d8..0eeafb767d8 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -32,6 +32,7 @@
 // is also useful to track which value is the "expected" value in
 // terms of error reporting.
 
+use super::bivariate::Bivariate;
 use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
@@ -39,7 +40,7 @@ use super::sub::Sub;
 use super::unify::InferCtxtMethodsForSimplyUnifiableTypes;
 use super::{InferCtxt, cres};
 use super::{MiscVariable, TypeTrace};
-use super::type_variable::{RelationDir, EqTo, SubtypeOf, SupertypeOf};
+use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
 
 use middle::subst;
 use middle::subst::{ErasedRegions, NonerasedRegions, Substs};
@@ -48,7 +49,7 @@ use middle::ty::{IntType, UintType};
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
 use middle::ty_fold;
-use middle::ty_fold::{TypeFoldable};
+use middle::ty_fold::{TypeFolder, TypeFoldable};
 use util::ppaux::Repr;
 
 use std::rc::Rc;
@@ -58,41 +59,32 @@ use syntax::abi;
 use syntax::codemap::Span;
 
 pub trait Combine<'tcx> : Sized {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx>;
     fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.infcx().tcx }
     fn tag(&self) -> String;
-    fn a_is_expected(&self) -> bool;
-    fn trace(&self) -> TypeTrace<'tcx>;
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx>;
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx>;
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx>;
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx>;
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx>;
+
+    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields().infcx }
+    fn a_is_expected(&self) -> bool { self.fields().a_is_expected }
+    fn trace(&self) -> TypeTrace<'tcx> { self.fields().trace.clone() }
+    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { self.fields().equate() }
+    fn bivariate<'a>(&'a self) -> Bivariate<'a, 'tcx> { self.fields().bivariate() }
+
+    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { self.fields().sub() }
+    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields().clone()) }
+    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields().clone()) }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>>;
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>;
+
+    fn tys_with_variance(&self, variance: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>;
+
     fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>>;
 
-    fn tps(&self,
-           _: subst::ParamSpace,
-           as_: &[Ty<'tcx>],
-           bs: &[Ty<'tcx>])
-           -> cres<'tcx, Vec<Ty<'tcx>>> {
-        // FIXME -- In general, we treat variance a bit wrong
-        // here. For historical reasons, we treat tps and Self
-        // as invariant. This is overly conservative.
-
-        if as_.len() != bs.len() {
-            return Err(ty::terr_ty_param_size(expected_found(self,
-                                                             as_.len(),
-                                                             bs.len())));
-        }
+    fn regions_with_variance(&self, variance: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>;
 
-        try!(as_.iter().zip(bs.iter())
-                .map(|(a, b)| self.equate().tys(*a, *b))
-                .collect::<cres<Vec<Ty>>>());
-        Ok(as_.to_vec())
-    }
+    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
 
     fn substs(&self,
               item_def_id: ast::DefId,
@@ -100,6 +92,11 @@ pub trait Combine<'tcx> : Sized {
               b_subst: &subst::Substs<'tcx>)
               -> cres<'tcx, subst::Substs<'tcx>>
     {
+        debug!("substs: item_def_id={} a_subst={} b_subst={}",
+               item_def_id.repr(self.infcx().tcx),
+               a_subst.repr(self.infcx().tcx),
+               b_subst.repr(self.infcx().tcx));
+
         let variances = if self.infcx().tcx.variance_computed.get() {
             Some(ty::item_variances(self.infcx().tcx, item_def_id))
         } else {
@@ -119,7 +116,8 @@ pub trait Combine<'tcx> : Sized {
         for &space in &subst::ParamSpace::all() {
             let a_tps = a_subst.types.get_slice(space);
             let b_tps = b_subst.types.get_slice(space);
-            let tps = try!(self.tps(space, a_tps, b_tps));
+            let t_variances = variances.map(|v| v.types.get_slice(space));
+            let tps = try!(relate_type_params(self, t_variances, a_tps, b_tps));
             substs.types.replace(space, tps);
         }
 
@@ -132,20 +130,7 @@ pub trait Combine<'tcx> : Sized {
                 for &space in &subst::ParamSpace::all() {
                     let a_regions = a.get_slice(space);
                     let b_regions = b.get_slice(space);
-
-                    let mut invariance = Vec::new();
-                    let r_variances = match variances {
-                        Some(variances) => {
-                            variances.regions.get_slice(space)
-                        }
-                        None => {
-                            for _ in a_regions {
-                                invariance.push(ty::Invariant);
-                            }
-                            &invariance[..]
-                        }
-                    };
-
+                    let r_variances = variances.map(|v| v.regions.get_slice(space));
                     let regions = try!(relate_region_params(self,
                                                             r_variances,
                                                             a_regions,
@@ -157,13 +142,34 @@ pub trait Combine<'tcx> : Sized {
 
         return Ok(substs);
 
+        fn relate_type_params<'tcx, C: Combine<'tcx>>(this: &C,
+                                                      variances: Option<&[ty::Variance]>,
+                                                      a_tys: &[Ty<'tcx>],
+                                                      b_tys: &[Ty<'tcx>])
+                                                      -> cres<'tcx, Vec<Ty<'tcx>>>
+        {
+            if a_tys.len() != b_tys.len() {
+                return Err(ty::terr_ty_param_size(expected_found(this,
+                                                                 a_tys.len(),
+                                                                 b_tys.len())));
+            }
+
+            range(0, a_tys.len()).map(|i| {
+                let a_ty = a_tys[i];
+                let b_ty = b_tys[i];
+                let v = variances.map_or(ty::Invariant, |v| v[i]);
+                this.tys_with_variance(v, a_ty, b_ty)
+            }).collect()
+        }
+
         fn relate_region_params<'tcx, C: Combine<'tcx>>(this: &C,
-                                                        variances: &[ty::Variance],
+                                                        variances: Option<&[ty::Variance]>,
                                                         a_rs: &[ty::Region],
                                                         b_rs: &[ty::Region])
-                                                        -> cres<'tcx, Vec<ty::Region>> {
+                                                        -> cres<'tcx, Vec<ty::Region>>
+        {
             let tcx = this.infcx().tcx;
-            let num_region_params = variances.len();
+            let num_region_params = a_rs.len();
 
             debug!("relate_region_params(\
                    a_rs={}, \
@@ -173,22 +179,18 @@ pub trait Combine<'tcx> : Sized {
                    b_rs.repr(tcx),
                    variances.repr(tcx));
 
-            assert_eq!(num_region_params, a_rs.len());
+            assert_eq!(num_region_params,
+                       variances.map_or(num_region_params,
+                                        |v| v.len()));
+
             assert_eq!(num_region_params, b_rs.len());
-            let mut rs = vec!();
-            for i in 0..num_region_params {
+
+            (0..a_rs.len()).map(|i| {
                 let a_r = a_rs[i];
                 let b_r = b_rs[i];
-                let variance = variances[i];
-                let r = match variance {
-                    ty::Invariant => this.equate().regions(a_r, b_r),
-                    ty::Covariant => this.regions(a_r, b_r),
-                    ty::Contravariant => this.contraregions(a_r, b_r),
-                    ty::Bivariant => Ok(a_r),
-                };
-                rs.push(try!(r));
-            }
-            Ok(rs)
+                let variance = variances.map_or(ty::Invariant, |v| v[i]);
+                this.regions_with_variance(variance, a_r, b_r)
+            }).collect()
         }
     }
 
@@ -241,7 +243,7 @@ pub trait Combine<'tcx> : Sized {
     }
 
     fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.contratys(a, b).and_then(|t| Ok(t))
+        self.tys_with_variance(ty::Contravariant, a, b).and_then(|t| Ok(t))
     }
 
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety>;
@@ -309,7 +311,7 @@ pub trait Combine<'tcx> : Sized {
                           b: &ty::ExistentialBounds<'tcx>)
                           -> cres<'tcx, ty::ExistentialBounds<'tcx>>
     {
-        let r = try!(self.contraregions(a.region_bound, b.region_bound));
+        let r = try!(self.regions_with_variance(ty::Contravariant, a.region_bound, b.region_bound));
         let nb = try!(self.builtin_bounds(a.builtin_bounds, b.builtin_bounds));
         let pb = try!(self.projection_bounds(&a.projection_bounds, &b.projection_bounds));
         Ok(ty::ExistentialBounds { region_bound: r,
@@ -322,11 +324,6 @@ pub trait Combine<'tcx> : Sized {
                       b: ty::BuiltinBounds)
                       -> cres<'tcx, ty::BuiltinBounds>;
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                  -> cres<'tcx, ty::Region>;
-
-    fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>;
-
     fn trait_refs(&self,
                   a: &ty::TraitRef<'tcx>,
                   b: &ty::TraitRef<'tcx>)
@@ -540,7 +537,8 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
       }
 
       (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
-            let r = try!(this.contraregions(*a_r, *b_r));
+            let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r));
+
             // FIXME(14985)  If we have mutable references to trait objects, we
             // used to use covariant subtyping. I have preserved this behaviour,
             // even though it is probably incorrect. So don't go down the usual
@@ -644,6 +642,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
         Equate((*self).clone())
     }
 
+    fn bivariate(&self) -> Bivariate<'f, 'tcx> {
+        Bivariate((*self).clone())
+    }
+
     fn sub(&self) -> Sub<'f, 'tcx> {
         Sub((*self).clone())
     }
@@ -697,7 +699,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
                         EqTo => {
                             self.generalize(a_ty, b_vid, false)
                         }
-                        SupertypeOf | SubtypeOf => {
+                        BiTo | SupertypeOf | SubtypeOf => {
                             self.generalize(a_ty, b_vid, true)
                         }
                     });
@@ -721,6 +723,10 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
             // to associate causes/spans with each of the relations in
             // the stack to get this right.
             match dir {
+                BiTo => {
+                    try!(self.bivariate().tys(a_ty, b_ty));
+                }
+
                 EqTo => {
                     try!(self.equate().tys(a_ty, b_ty));
                 }
@@ -730,7 +736,7 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> {
                 }
 
                 SupertypeOf => {
-                    try!(self.sub().contratys(a_ty, b_ty));
+                    try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty));
                 }
             }
         }
diff --git a/src/librustc/middle/infer/equate.rs b/src/librustc/middle/infer/equate.rs
index f0bde222864..7194e20b0cf 100644
--- a/src/librustc/middle/infer/equate.rs
+++ b/src/librustc/middle/infer/equate.rs
@@ -13,11 +13,7 @@ use middle::ty::{self, Ty};
 use middle::ty::TyVar;
 use middle::infer::combine::*;
 use middle::infer::{cres};
-use middle::infer::glb::Glb;
-use middle::infer::InferCtxt;
-use middle::infer::lub::Lub;
-use middle::infer::sub::Sub;
-use middle::infer::{TypeTrace, Subtype};
+use middle::infer::{Subtype};
 use middle::infer::type_variable::{EqTo};
 use util::ppaux::{Repr};
 
@@ -33,21 +29,20 @@ pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "eq".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Equate".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
-
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
+    fn tys_with_variance(&self, _: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        // Once we're equating, it doesn't matter what the variance is.
         self.tys(a, b)
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
+    fn regions_with_variance(&self, _: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        // Once we're equating, it doesn't matter what the variance is.
         self.regions(a, b)
     }
 
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 9aafa1f9fd2..53032f9b9ac 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -675,6 +675,17 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
                     sup,
                     "");
             }
+            infer::Operand(span) => {
+                self.tcx.sess.span_err(
+                    span,
+                    "lifetime of operand does not outlive \
+                     the operation");
+                note_and_explain_region(
+                    self.tcx,
+                    "the operand is only valid for ",
+                    sup,
+                    "");
+            }
             infer::AddrOf(span) => {
                 self.tcx.sess.span_err(
                     span,
@@ -1593,6 +1604,11 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
                     span,
                     "...so that return value is valid for the call");
             }
+            infer::Operand(span) => {
+                self.tcx.sess.span_err(
+                    span,
+                    "...so that operand is valid for operation");
+            }
             infer::AddrOf(span) => {
                 self.tcx.sess.span_note(
                     span,
diff --git a/src/librustc/middle/infer/glb.rs b/src/librustc/middle/infer/glb.rs
index ff0c2d92f45..33303808e84 100644
--- a/src/librustc/middle/infer/glb.rs
+++ b/src/librustc/middle/infer/glb.rs
@@ -10,12 +10,9 @@
 
 use super::combine::*;
 use super::lattice::*;
-use super::equate::Equate;
 use super::higher_ranked::HigherRankedRelations;
-use super::lub::Lub;
-use super::sub::Sub;
-use super::{cres, InferCtxt};
-use super::{TypeTrace, Subtype};
+use super::{cres};
+use super::Subtype;
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
@@ -34,15 +31,30 @@ pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "glb".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Glb".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Bivariant => self.bivariate().tys(a, b),
+            ty::Contravariant => self.lub().tys(a, b),
+        }
+    }
+
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Bivariant => self.bivariate().regions(a, b),
+            ty::Contravariant => self.lub().regions(a, b),
+        }
+    }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         let tcx = self.fields.infcx.tcx;
@@ -75,10 +87,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
         }
     }
 
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.lub().tys(a, b)
-    }
-
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
         match (a, b) {
           (Unsafety::Normal, _) | (_, Unsafety::Normal) => Ok(Unsafety::Normal),
@@ -104,11 +112,6 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
         Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                    -> cres<'tcx, ty::Region> {
-        self.lub().regions(a, b)
-    }
-
     fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
         super_lattice_tys(self, a, b)
     }
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 4469e27a5b0..a729156c88b 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -31,7 +31,7 @@ pub trait HigherRankedRelations<'tcx> {
         where T : Combineable<'tcx>;
 }
 
-trait InferCtxtExt<'tcx> {
+trait InferCtxtExt {
     fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region>;
 
     fn region_vars_confined_to_snapshot(&self,
@@ -371,7 +371,7 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
     }))
 }
 
-impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
+impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
     fn tainted_regions(&self, snapshot: &CombinedSnapshot, r: ty::Region) -> Vec<ty::Region> {
         self.region_vars.tainted(&snapshot.region_vars_snapshot, r)
     }
diff --git a/src/librustc/middle/infer/lub.rs b/src/librustc/middle/infer/lub.rs
index 204560e87ee..3570effa9fa 100644
--- a/src/librustc/middle/infer/lub.rs
+++ b/src/librustc/middle/infer/lub.rs
@@ -9,13 +9,10 @@
 // except according to those terms.
 
 use super::combine::*;
-use super::equate::Equate;
-use super::glb::Glb;
 use super::higher_ranked::HigherRankedRelations;
 use super::lattice::*;
-use super::sub::Sub;
-use super::{cres, InferCtxt};
-use super::{TypeTrace, Subtype};
+use super::{cres};
+use super::{Subtype};
 
 use middle::ty::{BuiltinBounds};
 use middle::ty::{self, Ty};
@@ -34,15 +31,30 @@ pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "lub".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
+    fn tag(&self) -> String { "Lub".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
 
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Bivariant => self.bivariate().tys(a, b),
+            ty::Contravariant => self.glb().tys(a, b),
+        }
+    }
+
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Bivariant => self.bivariate().regions(a, b),
+            ty::Contravariant => self.glb().regions(a, b),
+        }
+    }
 
     fn mts(&self, a: &ty::mt<'tcx>, b: &ty::mt<'tcx>) -> cres<'tcx, ty::mt<'tcx>> {
         let tcx = self.tcx();
@@ -70,10 +82,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
         }
     }
 
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        self.glb().tys(a, b)
-    }
-
     fn unsafeties(&self, a: Unsafety, b: Unsafety) -> cres<'tcx, Unsafety> {
         match (a, b) {
           (Unsafety::Unsafe, _) | (_, Unsafety::Unsafe) => Ok(Unsafety::Unsafe),
@@ -90,11 +98,6 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
         Ok(a.intersection(b))
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                    -> cres<'tcx, ty::Region> {
-        self.glb().regions(a, b)
-    }
-
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
                self.tag(),
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 00e377d65fe..b0576ff55ff 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -45,6 +45,7 @@ use self::lub::Lub;
 use self::unify::{UnificationTable, InferCtxtMethodsForSimplyUnifiableTypes};
 use self::error_reporting::ErrorReporting;
 
+pub mod bivariate;
 pub mod combine;
 pub mod equate;
 pub mod error_reporting;
@@ -209,6 +210,9 @@ pub enum SubregionOrigin<'tcx> {
     // Region in return type of invoked fn must enclose call
     CallReturn(Span),
 
+    // Operands must be in scope
+    Operand(Span),
+
     // Region resulting from a `&` expr must enclose the `&` expr
     AddrOf(Span),
 
@@ -1194,6 +1198,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
             CallRcvr(a) => a,
             CallArg(a) => a,
             CallReturn(a) => a,
+            Operand(a) => a,
             AddrOf(a) => a,
             AutoBorrow(a) => a,
             SafeDestructor(a) => a,
@@ -1257,6 +1262,7 @@ impl<'tcx> Repr<'tcx> for SubregionOrigin<'tcx> {
             CallRcvr(a) => format!("CallRcvr({})", a.repr(tcx)),
             CallArg(a) => format!("CallArg({})", a.repr(tcx)),
             CallReturn(a) => format!("CallReturn({})", a.repr(tcx)),
+            Operand(a) => format!("Operand({})", a.repr(tcx)),
             AddrOf(a) => format!("AddrOf({})", a.repr(tcx)),
             AutoBorrow(a) => format!("AutoBorrow({})", a.repr(tcx)),
             SafeDestructor(a) => format!("SafeDestructor({})", a.repr(tcx)),
diff --git a/src/librustc/middle/infer/sub.rs b/src/librustc/middle/infer/sub.rs
index 1e0d14544ff..33da3092b2a 100644
--- a/src/librustc/middle/infer/sub.rs
+++ b/src/librustc/middle/infer/sub.rs
@@ -10,12 +10,8 @@
 
 use super::combine::*;
 use super::{cres, CresCompare};
-use super::equate::Equate;
-use super::glb::Glb;
 use super::higher_ranked::HigherRankedRelations;
-use super::InferCtxt;
-use super::lub::Lub;
-use super::{TypeTrace, Subtype};
+use super::{Subtype};
 use super::type_variable::{SubtypeOf, SupertypeOf};
 
 use middle::ty::{BuiltinBounds};
@@ -37,28 +33,30 @@ pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> {
 }
 
 impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
-    fn infcx<'a>(&'a self) -> &'a InferCtxt<'a, 'tcx> { self.fields.infcx }
-    fn tag(&self) -> String { "sub".to_string() }
-    fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
-    fn trace(&self) -> TypeTrace<'tcx> { self.fields.trace.clone() }
-
-    fn equate<'a>(&'a self) -> Equate<'a, 'tcx> { Equate(self.fields.clone()) }
-    fn sub<'a>(&'a self) -> Sub<'a, 'tcx> { Sub(self.fields.clone()) }
-    fn lub<'a>(&'a self) -> Lub<'a, 'tcx> { Lub(self.fields.clone()) }
-    fn glb<'a>(&'a self) -> Glb<'a, 'tcx> { Glb(self.fields.clone()) }
-
-    fn contratys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
-        Sub(self.fields.switch_expected()).tys(b, a)
+    fn tag(&self) -> String { "Sub".to_string() }
+    fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
+
+    fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
+                         -> cres<'tcx, Ty<'tcx>>
+    {
+        match v {
+            ty::Invariant => self.equate().tys(a, b),
+            ty::Covariant => self.tys(a, b),
+            ty::Bivariant => self.bivariate().tys(a, b),
+            ty::Contravariant => Sub(self.fields.switch_expected()).tys(b, a),
+        }
     }
 
-    fn contraregions(&self, a: ty::Region, b: ty::Region)
-                     -> cres<'tcx, ty::Region> {
-                         let opp = CombineFields {
-                             a_is_expected: !self.fields.a_is_expected,
-                             ..self.fields.clone()
-                         };
-                         Sub(opp).regions(b, a)
-                     }
+    fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
+                             -> cres<'tcx, ty::Region>
+    {
+        match v {
+            ty::Invariant => self.equate().regions(a, b),
+            ty::Covariant => self.regions(a, b),
+            ty::Bivariant => self.bivariate().regions(a, b),
+            ty::Contravariant => Sub(self.fields.switch_expected()).regions(b, a),
+        }
+    }
 
     fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region> {
         debug!("{}.regions({}, {})",
diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs
index 9b8a4a84412..a856137af09 100644
--- a/src/librustc/middle/infer/type_variable.rs
+++ b/src/librustc/middle/infer/type_variable.rs
@@ -14,6 +14,7 @@ use self::UndoEntry::*;
 
 use middle::ty::{self, Ty};
 use std::cmp::min;
+use std::marker::PhantomData;
 use std::mem;
 use std::u32;
 use util::snapshot_vec as sv;
@@ -42,13 +43,13 @@ enum UndoEntry {
     Relate(ty::TyVid, ty::TyVid),
 }
 
-struct Delegate<'tcx>;
+struct Delegate<'tcx>(PhantomData<&'tcx ()>);
 
 type Relation = (RelationDir, ty::TyVid);
 
 #[derive(Copy, PartialEq, Debug)]
 pub enum RelationDir {
-    SubtypeOf, SupertypeOf, EqTo
+    SubtypeOf, SupertypeOf, EqTo, BiTo
 }
 
 impl RelationDir {
@@ -56,14 +57,15 @@ impl RelationDir {
         match self {
             SubtypeOf => SupertypeOf,
             SupertypeOf => SubtypeOf,
-            EqTo => EqTo
+            EqTo => EqTo,
+            BiTo => BiTo,
         }
     }
 }
 
 impl<'tcx> TypeVariableTable<'tcx> {
     pub fn new() -> TypeVariableTable<'tcx> {
-        TypeVariableTable { values: sv::SnapshotVec::new(Delegate) }
+        TypeVariableTable { values: sv::SnapshotVec::new(Delegate(PhantomData)) }
     }
 
     fn relations<'a>(&'a mut self, a: ty::TyVid) -> &'a mut Vec<Relation> {
diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs
index 235f3f994c6..0675cec6f69 100644
--- a/src/librustc/middle/infer/unify.rs
+++ b/src/librustc/middle/infer/unify.rs
@@ -18,6 +18,7 @@ use middle::infer::{uok, ures};
 use middle::infer::InferCtxt;
 use std::cell::RefCell;
 use std::fmt::Debug;
+use std::marker::PhantomData;
 use syntax::ast;
 use util::snapshot_vec as sv;
 
@@ -79,7 +80,7 @@ pub struct UnificationTable<K:UnifyKey> {
 /// made during the snapshot may either be *committed* or *rolled back*.
 pub struct Snapshot<K:UnifyKey> {
     // Link snapshot to the key type `K` of the table.
-    marker: marker::CovariantType<K>,
+    marker: marker::PhantomData<K>,
     snapshot: sv::Snapshot,
 }
 
@@ -92,7 +93,7 @@ pub struct Node<K:UnifyKey> {
 }
 
 #[derive(Copy)]
-pub struct Delegate<K>;
+pub struct Delegate<K>(PhantomData<K>);
 
 // We can't use V:LatticeValue, much as I would like to,
 // because frequently the pattern is that V=Option<U> for some
@@ -102,14 +103,14 @@ pub struct Delegate<K>;
 impl<K:UnifyKey> UnificationTable<K> {
     pub fn new() -> UnificationTable<K> {
         UnificationTable {
-            values: sv::SnapshotVec::new(Delegate),
+            values: sv::SnapshotVec::new(Delegate(PhantomData)),
         }
     }
 
     /// Starts a new snapshot. Each snapshot must be either
     /// rolled back or committed in a "LIFO" (stack) order.
     pub fn snapshot(&mut self) -> Snapshot<K> {
-        Snapshot { marker: marker::CovariantType::<K>,
+        Snapshot { marker: marker::PhantomData::<K>,
                    snapshot: self.values.start_snapshot() }
     }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index fd641bd709d..56c5928a132 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -306,12 +306,13 @@ lets_do_this! {
     ExchangeHeapLangItem,            "exchange_heap",           exchange_heap;
     OwnedBoxLangItem,                "owned_box",               owned_box;
 
+    PhantomFnItem,                   "phantom_fn",              phantom_fn;
     PhantomDataItem,                 "phantom_data",            phantom_data;
 
+    // Deprecated:
     CovariantTypeItem,               "covariant_type",          covariant_type;
     ContravariantTypeItem,           "contravariant_type",      contravariant_type;
     InvariantTypeItem,               "invariant_type",          invariant_type;
-
     CovariantLifetimeItem,           "covariant_lifetime",      covariant_lifetime;
     ContravariantLifetimeItem,       "contravariant_lifetime",  contravariant_lifetime;
     InvariantLifetimeItem,           "invariant_lifetime",      invariant_lifetime;
diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs
index 3a7522cafee..e199a60c370 100644
--- a/src/librustc/middle/traits/coherence.rs
+++ b/src/librustc/middle/traits/coherence.rs
@@ -10,24 +10,27 @@
 
 //! See `doc.rs` for high-level documentation
 
+use super::Normalized;
 use super::SelectionContext;
-use super::{Obligation, ObligationCause};
+use super::{ObligationCause};
+use super::PredicateObligation;
 use super::project;
 use super::util;
 
 use middle::subst::{Subst, TypeSpace};
-use middle::ty::{self, Ty};
-use middle::infer::InferCtxt;
+use middle::ty::{self, ToPolyTraitRef, Ty};
+use middle::infer::{self, InferCtxt};
 use std::collections::HashSet;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::DUMMY_SP;
 use util::ppaux::Repr;
 
-pub fn impl_can_satisfy(infcx: &InferCtxt,
-                        impl1_def_id: ast::DefId,
-                        impl2_def_id: ast::DefId)
-                        -> bool
+/// True if there exist types that satisfy both of the two given impls.
+pub fn overlapping_impls(infcx: &InferCtxt,
+                         impl1_def_id: ast::DefId,
+                         impl2_def_id: ast::DefId)
+                         -> bool
 {
     debug!("impl_can_satisfy(\
            impl1_def_id={}, \
@@ -35,28 +38,68 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
            impl1_def_id.repr(infcx.tcx),
            impl2_def_id.repr(infcx.tcx));
 
-    let param_env = ty::empty_parameter_environment(infcx.tcx);
-    let mut selcx = SelectionContext::intercrate(infcx, &param_env);
-    let cause = ObligationCause::dummy();
-
-    // `impl1` provides an implementation of `Foo<X,Y> for Z`.
-    let impl1_substs =
-        util::fresh_substs_for_impl(infcx, DUMMY_SP, impl1_def_id);
-    let impl1_trait_ref =
-        (*ty::impl_trait_ref(infcx.tcx, impl1_def_id).unwrap()).subst(infcx.tcx, &impl1_substs);
-    let impl1_trait_ref =
-        project::normalize(&mut selcx, cause.clone(), &impl1_trait_ref);
-
-    // Determine whether `impl2` can provide an implementation for those
-    // same types.
-    let obligation = Obligation::new(cause,
-                                     ty::Binder(ty::TraitPredicate {
-                                         trait_ref: Rc::new(impl1_trait_ref.value),
-                                     }));
-    debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx));
-    selcx.evaluate_impl(impl2_def_id, &obligation) &&
-        impl1_trait_ref.obligations.iter().all(
-            |o| selcx.evaluate_obligation(o))
+    let param_env = &ty::empty_parameter_environment(infcx.tcx);
+    let selcx = &mut SelectionContext::intercrate(infcx, param_env);
+    infcx.probe(|_| {
+        overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id)
+    })
+}
+
+/// Can the types from impl `a` be used to satisfy impl `b`?
+/// (Including all conditions)
+fn overlap(selcx: &mut SelectionContext,
+           a_def_id: ast::DefId,
+           b_def_id: ast::DefId)
+           -> bool
+{
+    let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id);
+    let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id);
+
+    // Does `a <: b` hold? If not, no overlap.
+    if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(),
+                                                  true,
+                                                  infer::Misc(DUMMY_SP),
+                                                  a_trait_ref.to_poly_trait_ref(),
+                                                  b_trait_ref.to_poly_trait_ref()) {
+        return false;
+    }
+
+    // Are any of the obligations unsatisfiable? If so, no overlap.
+    a_obligations.iter()
+                 .chain(b_obligations.iter())
+                 .all(|o| selcx.evaluate_obligation(o))
+}
+
+/// Instantiate fresh variables for all bound parameters of the impl
+/// and return the impl trait ref with those variables substituted.
+fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
+                                     impl_def_id: ast::DefId)
+                                     -> (Rc<ty::TraitRef<'tcx>>,
+                                         Vec<PredicateObligation<'tcx>>)
+{
+    let impl_substs =
+        &util::fresh_substs_for_impl(selcx.infcx(), DUMMY_SP, impl_def_id);
+    let impl_trait_ref =
+        ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap();
+    let impl_trait_ref =
+        impl_trait_ref.subst(selcx.tcx(), impl_substs);
+    let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } =
+        project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref);
+
+    let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id);
+    let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
+    let Normalized { value: predicates, obligations: normalization_obligations2 } =
+        project::normalize(selcx, ObligationCause::dummy(), &predicates);
+    let impl_obligations =
+        util::predicates_for_generics(selcx.tcx(), ObligationCause::dummy(), 0, &predicates);
+
+    let impl_obligations: Vec<_> =
+        impl_obligations.into_iter()
+        .chain(normalization_obligations1.into_iter())
+        .chain(normalization_obligations2.into_iter())
+        .collect();
+
+    (impl_trait_ref, impl_obligations)
 }
 
 pub enum OrphanCheckErr<'tcx> {
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index 57c9fa7a4d9..a63dcfc24a1 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -28,6 +28,7 @@ use util::ppaux::{Repr, UserString};
 pub use self::error_reporting::report_fulfillment_errors;
 pub use self::error_reporting::suggest_new_overflow_limit;
 pub use self::coherence::orphan_check;
+pub use self::coherence::overlapping_impls;
 pub use self::coherence::OrphanCheckErr;
 pub use self::fulfill::{FulfillmentContext, RegionObligation};
 pub use self::project::MismatchedProjectionTypes;
@@ -270,16 +271,6 @@ pub struct VtableObjectData<'tcx> {
     pub object_ty: Ty<'tcx>,
 }
 
-/// True if there exist types that satisfy both of the two given impls.
-pub fn overlapping_impls(infcx: &InferCtxt,
-                         impl1_def_id: ast::DefId,
-                         impl2_def_id: ast::DefId)
-                         -> bool
-{
-    coherence::impl_can_satisfy(infcx, impl1_def_id, impl2_def_id) &&
-    coherence::impl_can_satisfy(infcx, impl2_def_id, impl1_def_id)
-}
-
 /// Creates predicate obligations from the generic bounds.
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 496ce6be75c..0e298920841 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -132,6 +132,7 @@ pub enum MethodMatchedData {
 /// parameters) that would have to be inferred from the impl.
 #[derive(PartialEq,Eq,Debug,Clone)]
 enum SelectionCandidate<'tcx> {
+    PhantomFnCandidate,
     BuiltinCandidate(ty::BuiltinBound),
     ParamCandidate(ty::PolyTraitRef<'tcx>),
     ImplCandidate(ast::DefId),
@@ -793,8 +794,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                stack: &TraitObligationStack<'o, 'tcx>)
                                -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>>
     {
-        // Check for overflow.
-
         let TraitObligationStack { obligation, .. } = *stack;
 
         let mut candidates = SelectionCandidateSet {
@@ -802,6 +801,14 @@ 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.
 
@@ -1629,6 +1636,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     try!(self.confirm_builtin_candidate(obligation, builtin_bound))))
             }
 
+            PhantomFnCandidate |
             ErrorCandidate => {
                 Ok(VtableBuiltin(VtableBuiltinData { nested: VecPerParamSpace::empty() }))
             }
@@ -2295,6 +2303,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
     fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
+            PhantomFnCandidate => format!("PhantomFnCandidate"),
             ErrorCandidate => format!("ErrorCandidate"),
             BuiltinCandidate(b) => format!("BuiltinCandidate({:?})", b),
             ParamCandidate(ref a) => format!("ParamCandidate({})", a.repr(tcx)),
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index b1ea89c6574..e9908397f97 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3008,6 +3008,13 @@ impl<'tcx> TyS<'tcx> {
         assert_eq!(r, Some(self));
         walker
     }
+
+    pub fn as_opt_param_ty(&self) -> Option<ty::ParamTy> {
+        match self.sty {
+            ty::ty_param(ref d) => Some(d.clone()),
+            _ => None,
+        }
+    }
 }
 
 pub fn walk_ty<'tcx, F>(ty_root: Ty<'tcx>, mut f: F)
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 0494e1f7686..1639772103b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -306,10 +306,10 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
         // Crate-local:
         //
         // meh.
-        struct Visitor<'a, 'b: 'a, 'tcx: 'a + 'b> {
+        struct Visitor<'a> {
             traits: &'a mut AllTraitsVec,
         }
-        impl<'v,'a, 'b, 'tcx> visit::Visitor<'v> for Visitor<'a, 'b, 'tcx> {
+        impl<'v, 'a> visit::Visitor<'v> for Visitor<'a> {
             fn visit_item(&mut self, i: &'v ast::Item) {
                 match i.node {
                     ast::ItemTrait(..) => {
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 44a3b5167c7..82abff8c425 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -626,6 +626,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr);
         }
 
+        ast::ExprBinary(_, ref lhs, ref rhs) => {
+            // If you do `x OP y`, then the types of `x` and `y` must
+            // outlive the operation you are performing.
+            let lhs_ty = rcx.resolve_expr_type_adjusted(&**lhs);
+            let rhs_ty = rcx.resolve_expr_type_adjusted(&**rhs);
+            for &ty in [lhs_ty, rhs_ty].iter() {
+                type_must_outlive(rcx,
+                                  infer::Operand(expr.span),
+                                  ty,
+                                  ty::ReScope(CodeExtent::from_node_id(expr.id)));
+            }
+            visit::walk_expr(rcx, expr);
+        }
+
         ast::ExprUnary(op, ref lhs) if has_method_map => {
             let implicitly_ref_args = !ast_util::is_by_value_unop(op);
 
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index d124282d391..2601c4d2752 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -10,21 +10,22 @@
 
 use astconv::AstConv;
 use check::{FnCtxt, Inherited, blank_fn_ctxt, vtable, regionck};
+use constrained_type_params::identify_constrained_type_params;
 use CrateCtxt;
 use middle::region;
-use middle::subst;
+use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
 use middle::traits;
 use middle::ty::{self, Ty};
 use middle::ty::liberate_late_bound_regions;
 use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
-use util::ppaux::Repr;
+use util::ppaux::{Repr, UserString};
 
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_util::{local_def};
 use syntax::attr;
 use syntax::codemap::Span;
-use syntax::parse::token;
+use syntax::parse::token::{self, special_idents};
 use syntax::visit;
 use syntax::visit::Visitor;
 
@@ -38,6 +39,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() }
     }
 
+    fn tcx(&self) -> &ty::ctxt<'tcx> {
+        self.ccx.tcx
+    }
+
     /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
     /// well-formed, meaning that they do not require any constraints not declared in the struct
     /// definition itself. For example, this definition would be illegal:
@@ -96,19 +101,29 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             ast::ItemConst(..) => {
                 self.check_item_type(item);
             }
-            ast::ItemStruct(ref struct_def, _) => {
-                self.check_type_defn(item, |fcx| vec![struct_variant(fcx, &**struct_def)]);
+            ast::ItemStruct(ref struct_def, ref ast_generics) => {
+                self.check_type_defn(item, |fcx| {
+                    vec![struct_variant(fcx, &**struct_def)]
+                });
+
+                self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemEnum(ref enum_def, _) => {
-                self.check_type_defn(item, |fcx| enum_variants(fcx, enum_def));
+            ast::ItemEnum(ref enum_def, ref ast_generics) => {
+                self.check_type_defn(item, |fcx| {
+                    enum_variants(fcx, enum_def)
+                });
+
+                self.check_variances_for_type_defn(item, ast_generics);
             }
-            ast::ItemTrait(..) => {
+            ast::ItemTrait(_, ref ast_generics, _, _) => {
                 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());
             }
             _ => {}
         }
@@ -276,6 +291,123 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             }
         });
     }
+
+    fn check_variances_for_type_defn(&self,
+                                     item: &ast::Item,
+                                     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 variances = ty::item_variances(self.tcx(), item_def_id);
+
+        let mut constrained_parameters: HashSet<_> =
+            variances.types
+            .iter_enumerated()
+            .filter(|&(_, _, &variance)| variance != ty::Bivariant)
+            .map(|(space, index, _)| self.param_ty(ast_generics, space, index))
+            .collect();
+
+        identify_constrained_type_params(self.tcx(),
+                                         ty_predicates.predicates.as_slice(),
+                                         None,
+                                         &mut constrained_parameters);
+
+        for (space, index, _) in variances.types.iter_enumerated() {
+            let param_ty = self.param_ty(ast_generics, space, index);
+            if constrained_parameters.contains(&param_ty) {
+                continue;
+            }
+            let span = self.ty_param_span(ast_generics, item, space, index);
+            self.report_bivariance(span, param_ty.name, suggested_marker_id);
+        }
+
+        for (space, index, &variance) in variances.regions.iter_enumerated() {
+            if variance != ty::Bivariant {
+                continue;
+            }
+
+            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);
+        }
+    }
+
+    fn param_ty(&self,
+                ast_generics: &ast::Generics,
+                space: ParamSpace,
+                index: usize)
+                -> ty::ParamTy
+    {
+        let name = match space {
+            TypeSpace => ast_generics.ty_params[index].ident.name,
+            SelfSpace => special_idents::type_self.name,
+            FnSpace => self.tcx().sess.bug("Fn space occupied?"),
+        };
+
+        ty::ParamTy { space: space, idx: index as u32, name: name }
+    }
+
+    fn ty_param_span(&self,
+                     ast_generics: &ast::Generics,
+                     item: &ast::Item,
+                     space: ParamSpace,
+                     index: usize)
+                     -> Span
+    {
+        match space {
+            TypeSpace => ast_generics.ty_params[index].span,
+            SelfSpace => item.span,
+            FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"),
+        }
+    }
+
+    fn report_bivariance(&self,
+                         span: Span,
+                         param_name: ast::Name,
+                         suggested_marker_id: Option<ast::DefId>)
+    {
+        self.tcx().sess.span_err(
+            span,
+            &format!("parameter `{}` is never used",
+                     param_name.user_string(self.tcx()))[]);
+
+        match suggested_marker_id {
+            Some(def_id) => {
+                self.tcx().sess.span_help(
+                    span,
+                    format!("consider removing `{}` or using a marker such as `{}`",
+                            param_name.user_string(self.tcx()),
+                            ty::item_path_str(self.tcx(), def_id)).as_slice());
+            }
+            None => {
+                // no lang items, no help!
+            }
+        }
+    }
 }
 
 // Reject any predicates that do not involve a type parameter.
@@ -343,9 +475,9 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         match fk {
             visit::FkFnBlock | visit::FkItemFn(..) => {}
             visit::FkMethod(..) => {
-                match ty::impl_or_trait_item(self.ccx.tcx, local_def(id)) {
+                match ty::impl_or_trait_item(self.tcx(), local_def(id)) {
                     ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
-                        reject_shadowing_type_parameters(self.ccx.tcx, span, &ty_method.generics)
+                        reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics)
                     }
                     _ => {}
                 }
@@ -359,14 +491,14 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             &ast::TraitItem::ProvidedMethod(_) |
             &ast::TraitItem::TypeTraitItem(_) => {},
             &ast::TraitItem::RequiredMethod(ref method) => {
-                match ty::impl_or_trait_item(self.ccx.tcx, local_def(method.id)) {
+                match ty::impl_or_trait_item(self.tcx(), local_def(method.id)) {
                     ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
                         reject_non_type_param_bounds(
-                            self.ccx.tcx,
+                            self.tcx(),
                             method.span,
                             &ty_method.predicates);
                         reject_shadowing_type_parameters(
-                            self.ccx.tcx,
+                            self.tcx(),
                             method.span,
                             &ty_method.generics);
                     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 833daf083a7..0b78af18e26 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -87,6 +87,7 @@ There are some shortcomings in this design:
 
 use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region};
 use middle::def;
+use constrained_type_params::identify_constrained_type_params;
 use middle::lang_items::SizedTraitLangItem;
 use middle::region;
 use middle::resolve_lifetime;
@@ -1960,51 +1961,15 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
     let mut input_parameters: HashSet<_> =
         impl_trait_ref.iter()
                       .flat_map(|t| t.input_types().iter()) // Types in trait ref, if any
-                      .chain(Some(impl_scheme.ty).iter())  // Self type, always
+                      .chain(Some(impl_scheme.ty).iter())   // Self type, always
                       .flat_map(|t| t.walk())
-                      .filter_map(to_opt_param_ty)
+                      .filter_map(|t| t.as_opt_param_ty())
                       .collect();
 
-    loop {
-        let num_inputs = input_parameters.len();
-
-        let projection_predicates =
-            impl_predicates.predicates
-                           .iter()
-                           .filter_map(|predicate| {
-                               match *predicate {
-                                   // Ignore higher-ranked binders. For the purposes
-                                   // of this check, they don't matter because they
-                                   // only affect named regions, and we're just
-                                   // concerned about type parameters here.
-                                   ty::Predicate::Projection(ref data) => Some(data.0.clone()),
-                                   _ => None,
-                               }
-                           });
-
-        for projection in projection_predicates {
-            // Special case: watch out for some kind of sneaky attempt
-            // to project out an associated type defined by this very trait.
-            if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
-                continue;
-            }
-
-            let relies_only_on_inputs =
-                projection.projection_ty.trait_ref.input_types().iter()
-                .flat_map(|t| t.walk())
-                .filter_map(to_opt_param_ty)
-                .all(|t| input_parameters.contains(&t));
-
-            if relies_only_on_inputs {
-                input_parameters.extend(
-                    projection.ty.walk().filter_map(to_opt_param_ty));
-            }
-        }
-
-        if input_parameters.len() == num_inputs {
-            break;
-        }
-    }
+    identify_constrained_type_params(tcx,
+                                     impl_predicates.predicates.as_slice(),
+                                     impl_trait_ref,
+                                     &mut input_parameters);
 
     for (index, ty_param) in ast_generics.ty_params.iter().enumerate() {
         let param_ty = ty::ParamTy { space: TypeSpace,
@@ -2025,11 +1990,4 @@ fn enforce_impl_ty_params_are_constrained<'tcx>(tcx: &ty::ctxt<'tcx>,
             }
         }
     }
-
-    fn to_opt_param_ty<'tcx>(ty: Ty<'tcx>) -> Option<ty::ParamTy> {
-        match ty.sty {
-            ty::ty_param(ref d) => Some(d.clone()),
-            _ => None,
-        }
-    }
 }
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
new file mode 100644
index 00000000000..83d7e985000
--- /dev/null
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -0,0 +1,61 @@
+// 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.
+
+use middle::ty::{self};
+
+use std::collections::HashSet;
+use std::rc::Rc;
+
+pub fn identify_constrained_type_params<'tcx>(_tcx: &ty::ctxt<'tcx>,
+                                              predicates: &[ty::Predicate<'tcx>],
+                                              impl_trait_ref: Option<Rc<ty::TraitRef<'tcx>>>,
+                                              input_parameters: &mut HashSet<ty::ParamTy>)
+{
+    loop {
+        let num_inputs = input_parameters.len();
+
+        let projection_predicates =
+            predicates.iter()
+                      .filter_map(|predicate| {
+                          match *predicate {
+                              // Ignore higher-ranked binders. For the purposes
+                              // of this check, they don't matter because they
+                              // only affect named regions, and we're just
+                              // concerned about type parameters here.
+                              ty::Predicate::Projection(ref data) => Some(data.0.clone()),
+                              _ => None,
+                          }
+                      });
+
+        for projection in projection_predicates {
+            // Special case: watch out for some kind of sneaky attempt
+            // to project out an associated type defined by this very trait.
+            if Some(projection.projection_ty.trait_ref.clone()) == impl_trait_ref {
+                continue;
+            }
+
+            let relies_only_on_inputs =
+                projection.projection_ty.trait_ref.input_types()
+                                                  .iter()
+                                                  .flat_map(|t| t.walk())
+                                                  .filter_map(|t| t.as_opt_param_ty())
+                                                  .all(|t| input_parameters.contains(&t));
+
+            if relies_only_on_inputs {
+                input_parameters.extend(
+                    projection.ty.walk().filter_map(|t| t.as_opt_param_ty()));
+            }
+        }
+
+        if input_parameters.len() == num_inputs {
+            break;
+        }
+    }
+}
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 7498dc8179d..b5dca0bd4f6 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -123,6 +123,7 @@ mod check;
 mod rscope;
 mod astconv;
 mod collect;
+mod constrained_type_params;
 mod coherence;
 mod variance;
 
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index bf29bcd5123..1adcf133bf3 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -187,6 +187,22 @@
 //!   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.
 
 use self::VarianceTerm::*;
 use self::ParamKind::*;
@@ -199,7 +215,6 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace}
 use middle::ty::{self, Ty};
 use std::fmt;
 use std::rc::Rc;
-use std::iter::repeat;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
@@ -258,6 +273,11 @@ struct TermsContext<'a, 'tcx: 'a> {
 
     empty_variances: Rc<ty::ItemVariances>,
 
+    // For marker types, UnsafeCell, and other lang items where
+    // variance is hardcoded, records the item-id and the hardcoded
+    // variance.
+    lang_items: Vec<(ast::NodeId, Vec<ty::Variance>)>,
+
     // Maps from the node id of a type/generic parameter to the
     // corresponding inferred index.
     inferred_map: NodeMap<InferredIndex>,
@@ -269,7 +289,7 @@ struct TermsContext<'a, 'tcx: 'a> {
 #[derive(Copy, Debug, PartialEq)]
 enum ParamKind {
     TypeParam,
-    RegionParam
+    RegionParam,
 }
 
 struct InferredInfo<'a> {
@@ -279,6 +299,11 @@ struct InferredInfo<'a> {
     index: uint,
     param_id: ast::NodeId,
     term: VarianceTermPtr<'a>,
+
+    // Initial value to use for this parameter when inferring
+    // variance. For most parameters, this is Bivariant. But for lang
+    // items and input type parameters on traits, it is different.
+    initial_variance: ty::Variance,
 }
 
 fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
@@ -291,6 +316,8 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
         inferred_map: NodeMap(),
         inferred_infos: Vec::new(),
 
+        lang_items: lang_items(tcx),
+
         // cache and share the variance struct used for items with
         // no type/region parameters
         empty_variances: Rc::new(ty::ItemVariances {
@@ -304,7 +331,78 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
     terms_cx
 }
 
+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]),
+
+        // Deprecated:
+        (tcx.lang_items.covariant_type(), vec![ty::Covariant]),
+        (tcx.lang_items.contravariant_type(), vec![ty::Contravariant]),
+        (tcx.lang_items.invariant_type(), vec![ty::Invariant]),
+        (tcx.lang_items.covariant_lifetime(), vec![ty::Covariant]),
+        (tcx.lang_items.contravariant_lifetime(), vec![ty::Contravariant]),
+        (tcx.lang_items.invariant_lifetime(), vec![ty::Invariant]),
+
+        ];
+
+    all.into_iter()
+       .filter(|&(ref d,_)| d.is_some())
+       .filter(|&(ref d,_)| d.as_ref().unwrap().krate == ast::LOCAL_CRATE)
+       .map(|(d, v)| (d.unwrap().node, v))
+       .collect()
+}
+
 impl<'a, 'tcx> TermsContext<'a, 'tcx> {
+    fn add_inferreds_for_item(&mut self,
+                              item_id: ast::NodeId,
+                              has_self: bool,
+                              generics: &ast::Generics)
+    {
+        /*!
+         * Add "inferreds" for the generic parameters declared on this
+         * item. This has a lot of annoying parameters because we are
+         * trying to drive this from the AST, rather than the
+         * ty::Generics, so that we can get span info -- but this
+         * means we must accommodate syntactic distinctions.
+         */
+
+        // NB: In the code below for writing the results back into the
+        // tcx, we rely on the fact that all inferreds for a particular
+        // item are assigned continuous indices.
+
+        let inferreds_on_entry = self.num_inferred();
+
+        if has_self {
+            self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id);
+        }
+
+        for (i, p) in generics.lifetimes.iter().enumerate() {
+            let id = p.lifetime.id;
+            self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
+        }
+
+        for (i, p) in generics.ty_params.iter().enumerate() {
+            self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
+        }
+
+        // If this item has no type or lifetime parameters,
+        // then there are no variances to infer, so just
+        // insert an empty entry into the variance map.
+        // Arguably we could just leave the map empty in this
+        // case but it seems cleaner to be able to distinguish
+        // "invalid item id" from "item id with no
+        // parameters".
+        if self.num_inferred() == inferreds_on_entry {
+            let newly_added =
+                self.tcx.item_variance_map.borrow_mut().insert(
+                    ast_util::local_def(item_id),
+                    self.empty_variances.clone()).is_none();
+            assert!(newly_added);
+        }
+    }
+
     fn add_inferred(&mut self,
                     item_id: ast::NodeId,
                     kind: ParamKind,
@@ -313,21 +411,48 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
                     param_id: ast::NodeId) {
         let inf_index = InferredIndex(self.inferred_infos.len());
         let term = self.arena.alloc(InferredTerm(inf_index));
+        let initial_variance = self.pick_initial_variance(item_id, space, index);
         self.inferred_infos.push(InferredInfo { item_id: item_id,
                                                 kind: kind,
                                                 space: space,
                                                 index: index,
                                                 param_id: param_id,
-                                                term: term });
+                                                term: term,
+                                                initial_variance: initial_variance });
         let newly_added = self.inferred_map.insert(param_id, inf_index).is_none();
         assert!(newly_added);
 
-        debug!("add_inferred(item_id={}, \
+        debug!("add_inferred(item_path={}, \
+                item_id={}, \
                 kind={:?}, \
+                space={:?}, \
                 index={}, \
-                param_id={},
-                inf_index={:?})",
-                item_id, kind, index, param_id, inf_index);
+                param_id={}, \
+                inf_index={:?}, \
+                initial_variance={:?})",
+               ty::item_path_str(self.tcx, ast_util::local_def(item_id)),
+               item_id, kind, space, index, param_id, inf_index,
+               initial_variance);
+    }
+
+    fn pick_initial_variance(&self,
+                             item_id: ast::NodeId,
+                             space: ParamSpace,
+                             index: uint)
+                             -> ty::Variance
+    {
+        match space {
+            SelfSpace | FnSpace => {
+                ty::Bivariant
+            }
+
+            TypeSpace => {
+                match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
+                    Some(&(_, ref variances)) => variances[index],
+                    None => ty::Bivariant
+                }
+            }
+        }
     }
 
     fn num_inferred(&self) -> uint {
@@ -339,44 +464,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
     fn visit_item(&mut self, item: &ast::Item) {
         debug!("add_inferreds for item {}", item.repr(self.tcx));
 
-        let inferreds_on_entry = self.num_inferred();
-
-        // NB: In the code below for writing the results back into the
-        // tcx, we rely on the fact that all inferreds for a particular
-        // item are assigned continuous indices.
-        match item.node {
-            ast::ItemTrait(..) => {
-                self.add_inferred(item.id, TypeParam, SelfSpace, 0, item.id);
-            }
-            _ => { }
-        }
-
         match item.node {
             ast::ItemEnum(_, ref generics) |
-            ast::ItemStruct(_, ref generics) |
+            ast::ItemStruct(_, ref generics) => {
+                self.add_inferreds_for_item(item.id, false, generics);
+            }
             ast::ItemTrait(_, ref generics, _, _) => {
-                for (i, p) in generics.lifetimes.iter().enumerate() {
-                    let id = p.lifetime.id;
-                    self.add_inferred(item.id, RegionParam, TypeSpace, i, id);
-                }
-                for (i, p) in generics.ty_params.iter().enumerate() {
-                    self.add_inferred(item.id, TypeParam, TypeSpace, i, p.id);
-                }
-
-                // If this item has no type or lifetime parameters,
-                // then there are no variances to infer, so just
-                // insert an empty entry into the variance map.
-                // Arguably we could just leave the map empty in this
-                // case but it seems cleaner to be able to distinguish
-                // "invalid item id" from "item id with no
-                // parameters".
-                if self.num_inferred() == inferreds_on_entry {
-                    let newly_added = self.tcx.item_variance_map.borrow_mut().insert(
-                        ast_util::local_def(item.id),
-                        self.empty_variances.clone()).is_none();
-                    assert!(newly_added);
-                }
-
+                self.add_inferreds_for_item(item.id, true, generics);
                 visit::walk_item(self, item);
             }
 
@@ -404,16 +498,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
 struct ConstraintContext<'a, 'tcx: 'a> {
     terms_cx: TermsContext<'a, 'tcx>,
 
-    // These are the def-id of the std::marker::InvariantType,
-    // std::marker::InvariantLifetime, and so on. The arrays
-    // are indexed by the `ParamKind` (type, lifetime, self). Note
-    // that there are no marker types for self, so the entries for
-    // self are always None.
-    invariant_lang_items: [Option<ast::DefId>; 2],
-    covariant_lang_items: [Option<ast::DefId>; 2],
-    contravariant_lang_items: [Option<ast::DefId>; 2],
-    unsafe_cell_lang_item: Option<ast::DefId>,
-
     // These are pointers to common `ConstantTerm` instances
     covariant: VarianceTermPtr<'a>,
     contravariant: VarianceTermPtr<'a>,
@@ -433,40 +517,14 @@ struct Constraint<'a> {
 
 fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
                                         krate: &ast::Crate)
-                                        -> ConstraintContext<'a, 'tcx> {
-    let mut invariant_lang_items = [None; 2];
-    let mut covariant_lang_items = [None; 2];
-    let mut contravariant_lang_items = [None; 2];
-
-    covariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.covariant_type();
-    covariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.covariant_lifetime();
-
-    contravariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.contravariant_type();
-    contravariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.contravariant_lifetime();
-
-    invariant_lang_items[TypeParam as uint] =
-        terms_cx.tcx.lang_items.invariant_type();
-    invariant_lang_items[RegionParam as uint] =
-        terms_cx.tcx.lang_items.invariant_lifetime();
-
-    let unsafe_cell_lang_item = terms_cx.tcx.lang_items.unsafe_cell_type();
-
+                                        -> ConstraintContext<'a, 'tcx>
+{
     let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant));
     let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant));
     let invariant = terms_cx.arena.alloc(ConstantTerm(ty::Invariant));
     let bivariant = terms_cx.arena.alloc(ConstantTerm(ty::Bivariant));
     let mut constraint_cx = ConstraintContext {
         terms_cx: terms_cx,
-
-        invariant_lang_items: invariant_lang_items,
-        covariant_lang_items: covariant_lang_items,
-        contravariant_lang_items: contravariant_lang_items,
-        unsafe_cell_lang_item: unsafe_cell_lang_item,
-
         covariant: covariant,
         contravariant: contravariant,
         invariant: invariant,
@@ -487,7 +545,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
 
         match item.node {
             ast::ItemEnum(ref enum_definition, _) => {
-                let generics = &ty::lookup_item_type(tcx, did).generics;
+                let scheme = ty::lookup_item_type(tcx, did);
+
+                // Not entirely obvious: constraints on structs/enums do not
+                // affect the variance of their type parameters. See discussion
+                // in comment at top of module.
+                //
+                // self.add_constraints_from_generics(&scheme.generics);
 
                 // Hack: If we directly call `ty::enum_variants`, it
                 // annoyingly takes it upon itself to run off and
@@ -505,29 +569,48 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
                                                           &**ast_variant,
                                                           /*discriminant*/ 0);
                     for arg_ty in &variant.args {
-                        self.add_constraints_from_ty(generics, *arg_ty, self.covariant);
+                        self.add_constraints_from_ty(&scheme.generics, *arg_ty, self.covariant);
                     }
                 }
             }
 
             ast::ItemStruct(..) => {
-                let generics = &ty::lookup_item_type(tcx, did).generics;
+                let scheme = ty::lookup_item_type(tcx, did);
+
+                // Not entirely obvious: constraints on structs/enums do not
+                // affect the variance of their type parameters. See discussion
+                // in comment at top of module.
+                //
+                // self.add_constraints_from_generics(&scheme.generics);
+
                 let struct_fields = ty::lookup_struct_fields(tcx, did);
                 for field_info in &struct_fields {
                     assert_eq!(field_info.id.krate, ast::LOCAL_CRATE);
                     let field_ty = ty::node_id_to_type(tcx, field_info.id.node);
-                    self.add_constraints_from_ty(generics, field_ty, self.covariant);
+                    self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant);
                 }
             }
 
             ast::ItemTrait(..) => {
+                let trait_def = ty::lookup_trait_def(tcx, did);
+                let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds);
+                self.add_constraints_from_predicates(&trait_def.generics,
+                                                     &predicates[],
+                                                     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_sig(&method.generics,
-                                                          &method.fty.sig,
-                                                          self.covariant);
+                            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(_) => {}
                     }
@@ -544,9 +627,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
             ast::ItemTy(..) |
             ast::ItemImpl(..) |
             ast::ItemMac(..) => {
-                visit::walk_item(self, item);
             }
         }
+
+        visit::walk_item(self, item);
     }
 }
 
@@ -648,15 +732,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                          -> VarianceTermPtr<'a> {
         assert_eq!(param_def_id.krate, item_def_id.krate);
 
-        if self.invariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.invariant
-        } else if self.covariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.covariant
-        } else if self.contravariant_lang_items[kind as uint] == Some(item_def_id) {
-            self.contravariant
-        } else if kind == TypeParam && Some(item_def_id) == self.unsafe_cell_lang_item {
-            self.invariant
-        } else if param_def_id.krate == ast::LOCAL_CRATE {
+        if param_def_id.krate == ast::LOCAL_CRATE {
             // Parameter on an item defined within current crate:
             // variance not yet inferred, so return a symbolic
             // variance.
@@ -724,6 +800,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         }
     }
 
+    fn add_constraints_from_trait_ref(&mut self,
+                                      generics: &ty::Generics<'tcx>,
+                                      trait_ref: &ty::TraitRef<'tcx>,
+                                      variance: VarianceTermPtr<'a>) {
+        debug!("add_constraints_from_trait_ref: trait_ref={} variance={:?}",
+               trait_ref.repr(self.tcx()),
+               variance);
+
+        let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id);
+
+        self.add_constraints_from_substs(
+            generics,
+            trait_ref.def_id,
+            trait_def.generics.types.as_slice(),
+            trait_def.generics.regions.as_slice(),
+            trait_ref.substs,
+            variance);
+    }
+
     /// Adds constraints appropriate for an instance of `ty` appearing
     /// in a context with the generics defined in `generics` and
     /// ambient variance `variance`
@@ -731,7 +826,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                generics: &ty::Generics<'tcx>,
                                ty: Ty<'tcx>,
                                variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_ty(ty={})", ty.repr(self.tcx()));
+        debug!("add_constraints_from_ty(ty={}, variance={:?})",
+               ty.repr(self.tcx()),
+               variance);
 
         match ty.sty {
             ty::ty_bool |
@@ -754,6 +851,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_ty(generics, typ, variance);
             }
 
+
             ty::ty_ptr(ref mt) => {
                 self.add_constraints_from_mt(generics, mt, variance);
             }
@@ -797,27 +895,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
             }
 
             ty::ty_trait(ref data) => {
-                let trait_ref = data.principal_trait_ref_with_self_ty(self.tcx(),
-                                                                      self.tcx().types.err);
-                let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id());
-
-                // Traits never declare region parameters in the self
-                // space nor anything in the fn space.
-                assert!(trait_def.generics.regions.is_empty_in(subst::SelfSpace));
-                assert!(trait_def.generics.types.is_empty_in(subst::FnSpace));
-                assert!(trait_def.generics.regions.is_empty_in(subst::FnSpace));
+                let poly_trait_ref =
+                    data.principal_trait_ref_with_self_ty(self.tcx(),
+                                                          self.tcx().types.err);
 
                 // The type `Foo<T+'a>` is contravariant w/r/t `'a`:
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(generics, data.bounds.region_bound, contra);
 
-                self.add_constraints_from_substs(
-                    generics,
-                    trait_ref.def_id(),
-                    trait_def.generics.types.get_slice(subst::TypeSpace),
-                    trait_def.generics.regions.get_slice(subst::TypeSpace),
-                    trait_ref.substs(),
-                    variance);
+                // Ignore the SelfSpace, it is erased.
+                self.add_constraints_from_trait_ref(generics, &*poly_trait_ref.0, variance);
 
                 let projections = data.projection_bounds_with_self_ty(self.tcx(),
                                                                       self.tcx().types.err);
@@ -845,7 +932,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 self.add_constraints_from_sig(generics, sig, variance);
             }
 
-            ty::ty_infer(..) | ty::ty_err => {
+            ty::ty_err => {
+                // we encounter this when walking the trait references for object
+                // types, where we use ty_err as the Self type
+            }
+
+            ty::ty_infer(..) => {
                 self.tcx().sess.bug(
                     &format!("unexpected type encountered in \
                             variance inference: {}",
@@ -864,7 +956,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                    region_param_defs: &[ty::RegionParameterDef],
                                    substs: &subst::Substs<'tcx>,
                                    variance: VarianceTermPtr<'a>) {
-        debug!("add_constraints_from_substs(def_id={:?})", def_id);
+        debug!("add_constraints_from_substs(def_id={}, substs={}, variance={:?})",
+               def_id.repr(self.tcx()),
+               substs.repr(self.tcx()),
+               variance);
 
         for p in type_param_defs {
             let variance_decl =
@@ -872,6 +967,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                        p.space, p.index as uint);
             let variance_i = self.xform(variance, variance_decl);
             let substs_ty = *substs.types.get(p.space, p.index as uint);
+            debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
+                   variance_decl, variance_i);
             self.add_constraints_from_ty(generics, substs_ty, variance_i);
         }
 
@@ -885,6 +982,51 @@ 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)) => {
+                    self.add_constraints_from_ty(generics, data.0, variance);
+                    self.add_constraints_from_ty(generics, data.1, variance);
+                }
+
+                ty::Predicate::TypeOutlives(ty::Binder(ref data)) => {
+                    self.add_constraints_from_ty(generics, data.0, variance);
+
+                    let variance_r = self.xform(variance, self.contravariant);
+                    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);
+
+                    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,
@@ -969,7 +1111,12 @@ struct SolveContext<'a, 'tcx: 'a> {
 
 fn solve_constraints(constraints_cx: ConstraintContext) {
     let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
-    let solutions: Vec<_> = repeat(ty::Bivariant).take(terms_cx.num_inferred()).collect();
+
+    let solutions =
+        terms_cx.inferred_infos.iter()
+                               .map(|ii| ii.initial_variance)
+                               .collect();
+
     let mut solutions_cx = SolveContext {
         terms_cx: terms_cx,
         constraints: constraints,
@@ -1034,20 +1181,16 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
             let mut types = VecPerParamSpace::empty();
             let mut regions = VecPerParamSpace::empty();
 
-            while index < num_inferred &&
-                  inferred_infos[index].item_id == item_id {
+            while index < num_inferred && inferred_infos[index].item_id == item_id {
                 let info = &inferred_infos[index];
                 let variance = solutions[index];
                 debug!("Index {} Info {} / {:?} / {:?} Variance {:?}",
                        index, info.index, info.kind, info.space, variance);
                 match info.kind {
-                    TypeParam => {
-                        types.push(info.space, variance);
-                    }
-                    RegionParam => {
-                        regions.push(info.space, variance);
-                    }
+                    TypeParam => { types.push(info.space, variance); }
+                    RegionParam => { regions.push(info.space, variance); }
                 }
+
                 index += 1;
             }
 
@@ -1144,3 +1287,4 @@ fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
         (x, ty::Bivariant) | (ty::Bivariant, x) => x,
     }
 }
+
diff --git a/src/libstd/collections/hash/state.rs b/src/libstd/collections/hash/state.rs
index 79e01304fb8..7e6dd45b51e 100644
--- a/src/libstd/collections/hash/state.rs
+++ b/src/libstd/collections/hash/state.rs
@@ -11,6 +11,7 @@
 use clone::Clone;
 use default::Default;
 use hash;
+use marker;
 
 /// A trait representing stateful hashes which can be used to hash keys in a
 /// `HashMap`.
@@ -37,7 +38,7 @@ pub trait HashState {
 ///
 /// This struct has is 0-sized and does not need construction.
 #[unstable(feature = "std_misc", reason = "hasher stuff is unclear")]
-pub struct DefaultState<H>;
+pub struct DefaultState<H>(marker::PhantomData<H>);
 
 impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
     type Hasher = H;
@@ -45,9 +46,9 @@ impl<H: Default + hash::Hasher> HashState for DefaultState<H> {
 }
 
 impl<H> Clone for DefaultState<H> {
-    fn clone(&self) -> DefaultState<H> { DefaultState }
+    fn clone(&self) -> DefaultState<H> { DefaultState(marker::PhantomData) }
 }
 
 impl<H> Default for DefaultState<H> {
-    fn default() -> DefaultState<H> { DefaultState }
+    fn default() -> DefaultState<H> { DefaultState(marker::PhantomData) }
 }
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 7114da93ea0..f301f6db92f 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -23,8 +23,8 @@ use num::{Int, UnsignedInt};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
-use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory};
-use rt::heap::{allocate, deallocate};
+use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory};
+use rt::heap::{allocate, deallocate, EMPTY};
 use collections::hash_state::HashState;
 
 const EMPTY_BUCKET: u64 = 0u64;
@@ -69,10 +69,11 @@ const EMPTY_BUCKET: u64 = 0u64;
 pub struct RawTable<K, V> {
     capacity: usize,
     size:     usize,
-    hashes:   *mut u64,
+    hashes:   Unique<u64>,
+
     // Because K/V do not appear directly in any of the types in the struct,
     // inform rustc that in fact instances of K and V are reachable from here.
-    marker:   marker::CovariantType<(K,V)>,
+    marker:   marker::PhantomData<(K,V)>,
 }
 
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
@@ -81,7 +82,8 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
 struct RawBucket<K, V> {
     hash: *mut u64,
     key:  *mut K,
-    val:  *mut V
+    val:  *mut V,
+    _marker: marker::PhantomData<(K,V)>,
 }
 
 impl<K,V> Copy for RawBucket<K,V> {}
@@ -187,11 +189,12 @@ fn can_alias_safehash_as_u64() {
 }
 
 impl<K, V> RawBucket<K, V> {
-    unsafe fn offset(self, count: int) -> RawBucket<K, V> {
+    unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
         RawBucket {
             hash: self.hash.offset(count),
             key:  self.key.offset(count),
             val:  self.val.offset(count),
+            _marker: marker::PhantomData,
         }
     }
 }
@@ -584,10 +587,11 @@ impl<K, V> RawTable<K, V> {
             return RawTable {
                 size: 0,
                 capacity: 0,
-                hashes: ptr::null_mut(),
-                marker: marker::CovariantType,
+                hashes: Unique::new(EMPTY as *mut u64),
+                marker: marker::PhantomData,
             };
         }
+
         // No need for `checked_mul` before a more restrictive check performed
         // later in this method.
         let hashes_size = capacity * size_of::<u64>();
@@ -623,8 +627,8 @@ impl<K, V> RawTable<K, V> {
         RawTable {
             capacity: capacity,
             size:     0,
-            hashes:   hashes,
-            marker:   marker::CovariantType,
+            hashes:   Unique::new(hashes),
+            marker:   marker::PhantomData,
         }
     }
 
@@ -632,16 +636,17 @@ impl<K, V> RawTable<K, V> {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
 
-        let buffer = self.hashes as *mut u8;
+        let buffer = *self.hashes as *mut u8;
         let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
                                                            keys_size, min_align_of::<K>(),
                                                            min_align_of::<V>());
 
         unsafe {
             RawBucket {
-                hash: self.hashes,
+                hash: *self.hashes,
                 key:  buffer.offset(keys_offset as isize) as *mut K,
-                val:  buffer.offset(vals_offset as isize) as *mut V
+                val:  buffer.offset(vals_offset as isize) as *mut V,
+                _marker: marker::PhantomData,
             }
         }
     }
@@ -651,7 +656,7 @@ impl<K, V> RawTable<K, V> {
     pub fn new(capacity: usize) -> RawTable<K, V> {
         unsafe {
             let ret = RawTable::new_uninitialized(capacity);
-            zero_memory(ret.hashes, capacity);
+            zero_memory(*ret.hashes, capacity);
             ret
         }
     }
@@ -673,7 +678,7 @@ impl<K, V> RawTable<K, V> {
             hashes_end: unsafe {
                 self.hashes.offset(self.capacity as isize)
             },
-            marker: marker::ContravariantLifetime,
+            marker: marker::PhantomData,
         }
     }
 
@@ -698,7 +703,7 @@ impl<K, V> RawTable<K, V> {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
-                marker: marker::ContravariantLifetime,
+                marker: marker::PhantomData,
             },
             table: self,
         }
@@ -711,7 +716,7 @@ impl<K, V> RawTable<K, V> {
             iter: RawBuckets {
                 raw: raw,
                 hashes_end: hashes_end,
-                marker: marker::ContravariantLifetime::<'static>,
+                marker: marker::PhantomData,
             },
             table: self,
         }
@@ -725,7 +730,7 @@ impl<K, V> RawTable<K, V> {
             raw: raw_bucket.offset(self.capacity as isize),
             hashes_end: raw_bucket.hash,
             elems_left: self.size,
-            marker:     marker::ContravariantLifetime,
+            marker:     marker::PhantomData,
         }
     }
 }
@@ -735,7 +740,13 @@ impl<K, V> RawTable<K, V> {
 struct RawBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
     hashes_end: *mut u64,
-    marker: marker::ContravariantLifetime<'a>,
+
+    // Strictly speaking, this should be &'a (K,V), but that would
+    // require that K:'a, and we often use RawBuckets<'static...> for
+    // move iterations, so that messes up a lot of other things. So
+    // just use `&'a (K,V)` as this is not a publicly exposed type
+    // anyway.
+    marker: marker::PhantomData<&'a ()>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
@@ -744,7 +755,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
         RawBuckets {
             raw: self.raw,
             hashes_end: self.hashes_end,
-            marker: marker::ContravariantLifetime,
+            marker: marker::PhantomData,
         }
     }
 }
@@ -776,7 +787,11 @@ struct RevMoveBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
     hashes_end: *mut u64,
     elems_left: usize,
-    marker: marker::ContravariantLifetime<'a>,
+
+    // As above, `&'a (K,V)` would seem better, but we often use
+    // 'static for the lifetime, and this is not a publicly exposed
+    // type.
+    marker: marker::PhantomData<&'a ()>,
 }
 
 impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
@@ -983,9 +998,10 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
 #[unsafe_destructor]
 impl<K, V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.hashes.is_null() {
+        if self.capacity == 0 {
             return;
         }
+
         // This is done in reverse because we've likely partially taken
         // some elements out with `.into_iter()` from the front.
         // Check if the size is 0, so we don't do a useless scan when
@@ -1003,7 +1019,7 @@ impl<K, V> Drop for RawTable<K, V> {
                                                     vals_size, min_align_of::<V>());
 
         unsafe {
-            deallocate(self.hashes as *mut u8, size, align);
+            deallocate(*self.hashes as *mut u8, size, align);
             // Remember how everything was allocated out of one buffer
             // during initialization? We only need one call to free here.
         }
diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs
index 21282a0c28a..fc3deb67f41 100644
--- a/src/libstd/old_io/mod.rs
+++ b/src/libstd/old_io/mod.rs
@@ -252,7 +252,7 @@ use error::Error;
 use fmt;
 use isize;
 use iter::{Iterator, IteratorExt};
-use marker::Sized;
+use marker::{PhantomFn, Sized};
 use mem::transmute;
 use ops::FnOnce;
 use option::Option;
@@ -433,7 +433,7 @@ pub enum IoErrorKind {
 }
 
 /// A trait that lets you add a `detail` to an IoError easily
-trait UpdateIoError<T> {
+trait UpdateIoError {
     /// Returns an IoError with updated description and detail
     fn update_err<D>(self, desc: &'static str, detail: D) -> Self where
         D: FnOnce(&IoError) -> String;
@@ -446,7 +446,7 @@ trait UpdateIoError<T> {
     fn update_desc(self, desc: &'static str) -> Self;
 }
 
-impl<T> UpdateIoError<T> for IoResult<T> {
+impl<T> UpdateIoError for IoResult<T> {
     fn update_err<D>(self, desc: &'static str, detail: D) -> IoResult<T> where
         D: FnOnce(&IoError) -> String,
     {
@@ -1572,7 +1572,9 @@ pub trait Seek {
 /// connections.
 ///
 /// Doing so produces some sort of Acceptor.
-pub trait Listener<T, A: Acceptor<T>> {
+pub trait Listener<T, A: Acceptor<T>>
+    : PhantomFn<T,T> // FIXME should be an assoc type anyhow
+{
     /// Spin up the listener and start queuing incoming connections
     ///
     /// # Error
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index 3137d779c40..3653e7e31d5 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -153,7 +153,7 @@ use any::Any;
 use cell::UnsafeCell;
 use fmt;
 use io;
-use marker;
+use marker::PhantomData;
 use old_io::stdio;
 use rt::{self, unwind};
 use sync::{Mutex, Condvar, Arc};
@@ -260,7 +260,7 @@ impl Builder {
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
         self.spawn_inner(Thunk::new(f)).map(|inner| {
-            JoinGuard { inner: inner, _marker: marker::CovariantType }
+            JoinGuard { inner: inner, _marker: PhantomData }
         })
     }
 
@@ -642,7 +642,7 @@ impl Drop for JoinHandle {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinGuard<'a, T: 'a> {
     inner: JoinInner<T>,
-    _marker: marker::CovariantType<&'a T>,
+    _marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 8c2b9edfb22..4e4a571ede7 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -45,11 +45,11 @@ fn no_prelude(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "no_implicit_prelude")
 }
 
-struct StandardLibraryInjector<'a> {
-    alt_std_name: Option<String>
+struct StandardLibraryInjector {
+    alt_std_name: Option<String>,
 }
 
-impl<'a> fold::Folder for StandardLibraryInjector<'a> {
+impl fold::Folder for StandardLibraryInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
 
         // The name to use in `extern crate "name" as std;`
@@ -80,9 +80,10 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Cr
     fold.fold_crate(krate)
 }
 
-struct PreludeInjector<'a>;
+struct PreludeInjector;
 
-impl<'a> fold::Folder for PreludeInjector<'a> {
+
+impl fold::Folder for PreludeInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         // only add `use std::prelude::*;` if there wasn't a
         // `#![no_implicit_prelude]` at the crate level.
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 304f370a199..5418533aff1 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -50,7 +50,6 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![deny(missing_docs)]
 
-#![feature(core)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(int_uint)]
diff --git a/src/test/auxiliary/coherence-orphan-lib.rs b/src/test/auxiliary/coherence-orphan-lib.rs
index 2e5d18b58f2..cc42b288e66 100644
--- a/src/test/auxiliary/coherence-orphan-lib.rs
+++ b/src/test/auxiliary/coherence-orphan-lib.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait TheTrait<T> {
+pub trait TheTrait<T> : ::std::marker::PhantomFn<T> {
     fn the_fn(&self);
 }
 
diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/auxiliary/default_type_params_xc.rs
index d12f716decf..0a65174911e 100644
--- a/src/test/auxiliary/default_type_params_xc.rs
+++ b/src/test/auxiliary/default_type_params_xc.rs
@@ -12,4 +12,5 @@ pub struct Heap;
 
 pub struct FakeHeap;
 
-pub struct FakeVec<T, A = FakeHeap>;
+pub struct FakeVec<T, A = FakeHeap> { pub f: Option<(T,A)> }
+
diff --git a/src/test/auxiliary/inner_static.rs b/src/test/auxiliary/inner_static.rs
index 94acea06618..ca5c6072cb3 100644
--- a/src/test/auxiliary/inner_static.rs
+++ b/src/test/auxiliary/inner_static.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct A<T>;
-pub struct B<T>;
+pub struct A<T> { pub v: T }
+pub struct B<T> { pub v: T }
 
 pub mod test {
-    pub struct A<T>;
+    pub struct A<T> { pub v: T }
 
     impl<T> A<T> {
         pub fn foo(&self) -> int {
@@ -52,9 +52,9 @@ impl<T> B<T> {
 }
 
 pub fn foo() -> int {
-    let a = A::<()>;
-    let b = B::<()>;
-    let c = test::A::<()>;
+    let a = A { v: () };
+    let b = B { v: () };
+    let c = test::A { v: () };
     return a.foo() + a.bar() +
            b.foo() + b.bar() +
            c.foo() + c.bar();
diff --git a/src/test/auxiliary/issue-14421.rs b/src/test/auxiliary/issue-14421.rs
index 7c69cba179c..a48088609f9 100644
--- a/src/test/auxiliary/issue-14421.rs
+++ b/src/test/auxiliary/issue-14421.rs
@@ -10,6 +10,7 @@
 
 #![crate_type="lib"]
 #![deny(warnings)]
+#![allow(dead_code)]
 
 pub use src::aliases::B;
 pub use src::hidden_core::make;
@@ -23,9 +24,9 @@ mod src {
     pub mod hidden_core {
         use super::aliases::B;
 
-        pub struct A<T>;
+        pub struct A<T> { t: T }
 
-        pub fn make() -> B { A }
+        pub fn make() -> B { A { t: 1.0 } }
 
         impl<T> A<T> {
             pub fn foo(&mut self) { println!("called foo"); }
diff --git a/src/test/auxiliary/issue-16643.rs b/src/test/auxiliary/issue-16643.rs
index c5b3fceaf4a..b590160a0c2 100644
--- a/src/test/auxiliary/issue-16643.rs
+++ b/src/test/auxiliary/issue-16643.rs
@@ -10,7 +10,7 @@
 
 #![crate_type = "lib"]
 
-pub struct TreeBuilder<H>;
+pub struct TreeBuilder<H> { pub h: H }
 
 impl<H> TreeBuilder<H> {
     pub fn process_token(&mut self) {
diff --git a/src/test/auxiliary/issue-17662.rs b/src/test/auxiliary/issue-17662.rs
index be10ca1dd8f..fb55a077005 100644
--- a/src/test/auxiliary/issue-17662.rs
+++ b/src/test/auxiliary/issue-17662.rs
@@ -11,7 +11,7 @@
 #![crate_type = "lib"]
 
 pub trait Foo<'a, T> {
-    fn foo(&self) -> T;
+    fn foo(&'a self) -> T;
 }
 
 pub fn foo<'a, T>(x: &'a Foo<'a, T>) -> T {
diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/auxiliary/issue-2380.rs
index 8eb6cd6e263..96f33f97a69 100644
--- a/src/test/auxiliary/issue-2380.rs
+++ b/src/test/auxiliary/issue-2380.rs
@@ -14,7 +14,10 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub trait i<T> { }
+pub trait i<T>
+{
+    fn dummy(&self, t: T) -> T { panic!() }
+}
 
 pub fn f<T>() -> Box<i<T>+'static> {
     impl<T> i<T> for () { }
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs
index e3ce4e8f656..89b3b56121a 100644
--- a/src/test/auxiliary/issue-2526.rs
+++ b/src/test/auxiliary/issue-2526.rs
@@ -13,8 +13,11 @@
 
 #![feature(unsafe_destructor)]
 
+use std::marker;
+
 struct arc_destruct<T> {
-  _data: int,
+    _data: int,
+    _marker: marker::PhantomData<T>
 }
 
 #[unsafe_destructor]
@@ -24,7 +27,8 @@ impl<T: Sync> Drop for arc_destruct<T> {
 
 fn arc_destruct<T: Sync>(data: int) -> arc_destruct<T> {
     arc_destruct {
-        _data: data
+        _data: data,
+        _marker: marker::PhantomData
     }
 }
 
diff --git a/src/test/auxiliary/issue_20389.rs b/src/test/auxiliary/issue_20389.rs
index 7a378b06df9..4ce7e3079e3 100644
--- a/src/test/auxiliary/issue_20389.rs
+++ b/src/test/auxiliary/issue_20389.rs
@@ -10,4 +10,5 @@
 
 pub trait T {
     type C;
+    fn dummy(&self) { }
 }
diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/auxiliary/issue_3907.rs
index 2e254e5431d..545e15fe166 100644
--- a/src/test/auxiliary/issue_3907.rs
+++ b/src/test/auxiliary/issue_3907.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
+use std::marker::MarkerTrait;
+
+pub trait Foo : MarkerTrait {
     fn bar();
 }
 
diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/auxiliary/issue_8401.rs
index 0831993119a..9006a5d1775 100644
--- a/src/test/auxiliary/issue_8401.rs
+++ b/src/test/auxiliary/issue_8401.rs
@@ -12,7 +12,9 @@
 
 use std::mem;
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
diff --git a/src/test/auxiliary/issue_9123.rs b/src/test/auxiliary/issue_9123.rs
index 000cc100a12..4f2792aebcd 100644
--- a/src/test/auxiliary/issue_9123.rs
+++ b/src/test/auxiliary/issue_9123.rs
@@ -15,5 +15,6 @@ pub trait X {
         fn f() { }
         f();
     }
+    fn dummy(&self) { }
 }
 
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs
index 834667968c8..b9cc20b63cc 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/auxiliary/lang-item-public.rs
@@ -12,8 +12,12 @@
 #![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 {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang="panic"]
 fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
@@ -25,6 +29,8 @@ extern fn stack_exhausted() {}
 extern fn eh_personality() {}
 
 #[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {
+    // Empty.
+}
 
 
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index 01b2b748ba9..fb535eb8336 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -96,7 +96,7 @@ pub trait Trait {
 impl Trait for MethodTester {}
 
 #[unstable(feature = "test_feature")]
-pub trait UnstableTrait {}
+pub trait UnstableTrait { fn dummy(&self) { } }
 
 #[stable(feature = "test_feature", since = "1.0.0")]
 #[deprecated(since = "1.0.0")]
diff --git a/src/test/auxiliary/nested_item.rs b/src/test/auxiliary/nested_item.rs
index 21784bda27a..fc1bea5a9fd 100644
--- a/src/test/auxiliary/nested_item.rs
+++ b/src/test/auxiliary/nested_item.rs
@@ -25,7 +25,7 @@ impl Foo {
 }
 
 // issue 8134
-pub struct Parser<T>;
+pub struct Parser<T>(T);
 impl<T: std::iter::Iterator<Item=char>> Parser<T> {
     fn in_doctype(&mut self) {
         static DOCTYPEPattern: [char; 6] = ['O', 'C', 'T', 'Y', 'P', 'E'];
diff --git a/src/test/auxiliary/orphan_check_diagnostics.rs b/src/test/auxiliary/orphan_check_diagnostics.rs
index 7647f159401..cf3e9903b5a 100644
--- a/src/test/auxiliary/orphan_check_diagnostics.rs
+++ b/src/test/auxiliary/orphan_check_diagnostics.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait RemoteTrait {}
+pub trait RemoteTrait { fn dummy(&self) { } }
diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/auxiliary/overloaded_autoderef_xc.rs
index caa9bbe5736..3c8cba13ae7 100644
--- a/src/test/auxiliary/overloaded_autoderef_xc.rs
+++ b/src/test/auxiliary/overloaded_autoderef_xc.rs
@@ -11,7 +11,8 @@
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
-    pub helper: H
+    pub helper: H,
+    pub value: Option<T>
 }
 
 trait Helper<T> {
@@ -34,6 +35,6 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
 
 // Test cross-crate autoderef + vtable.
 pub fn check<T: PartialEq>(x: T, y: T) -> bool {
-    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x), value: None };
     d.eq(&y)
 }
diff --git a/src/test/auxiliary/private_trait_xc.rs b/src/test/auxiliary/private_trait_xc.rs
index 37ee10c8d37..42691579491 100644
--- a/src/test/auxiliary/private_trait_xc.rs
+++ b/src/test/auxiliary/private_trait_xc.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/auxiliary/svh-a-base.rs
index 12833daf604..04f1062c16f 100644
--- a/src/test/auxiliary/svh-a-base.rs
+++ b/src/test/auxiliary/svh-a-base.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/auxiliary/svh-a-change-lit.rs
index 9e74bf28135..fabd2289e9a 100644
--- a/src/test/auxiliary/svh-a-change-lit.rs
+++ b/src/test/auxiliary/svh-a-change-lit.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/auxiliary/svh-a-change-significant-cfg.rs
index c900550041b..3fdb861bd40 100644
--- a/src/test/auxiliary/svh-a-change-significant-cfg.rs
+++ b/src/test/auxiliary/svh-a-change-significant-cfg.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/auxiliary/svh-a-change-trait-bound.rs
index 04f8eb3cf9b..3116d24673d 100644
--- a/src/test/auxiliary/svh-a-change-trait-bound.rs
+++ b/src/test/auxiliary/svh-a-change-trait-bound.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/auxiliary/svh-a-change-type-arg.rs
index c7e0a18768a..b49a1533628 100644
--- a/src/test/auxiliary/svh-a-change-type-arg.rs
+++ b/src/test/auxiliary/svh-a-change-type-arg.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/auxiliary/svh-a-change-type-ret.rs
index 5100af32318..6562a93135f 100644
--- a/src/test/auxiliary/svh-a-change-type-ret.rs
+++ b/src/test/auxiliary/svh-a-change-type-ret.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/auxiliary/svh-a-change-type-static.rs
index 077c33cb90d..c7b392c6ee8 100644
--- a/src/test/auxiliary/svh-a-change-type-static.rs
+++ b/src/test/auxiliary/svh-a-change-type-static.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/auxiliary/svh-a-comment.rs
index d481fa5a1fa..450f6102026 100644
--- a/src/test/auxiliary/svh-a-comment.rs
+++ b/src/test/auxiliary/svh-a-comment.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/auxiliary/svh-a-doc.rs
index 9e99a355ac1..c000737c854 100644
--- a/src/test/auxiliary/svh-a-doc.rs
+++ b/src/test/auxiliary/svh-a-doc.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/auxiliary/svh-a-macro.rs
index b8dd497ac99..1e12659dc4b 100644
--- a/src/test/auxiliary/svh-a-macro.rs
+++ b/src/test/auxiliary/svh-a-macro.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/auxiliary/svh-a-no-change.rs
index 12833daf604..04f1062c16f 100644
--- a/src/test/auxiliary/svh-a-no-change.rs
+++ b/src/test/auxiliary/svh-a-no-change.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/auxiliary/svh-a-redundant-cfg.rs
index 690ddc670f5..1e82b74f1ef 100644
--- a/src/test/auxiliary/svh-a-redundant-cfg.rs
+++ b/src/test/auxiliary/svh-a-redundant-cfg.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/auxiliary/svh-a-whitespace.rs
index 216e8e997f2..3c3dac9cdab 100644
--- a/src/test/auxiliary/svh-a-whitespace.rs
+++ b/src/test/auxiliary/svh-a-whitespace.rs
@@ -15,12 +15,14 @@
 
 #![crate_name = "a"]
 
+use std::marker::MarkerTrait;
+
 macro_rules! three {
     () => { 3 }
 }
 
-pub trait U {}
-pub trait V {}
+pub trait U : MarkerTrait {}
+pub trait V : MarkerTrait {}
 impl U for () {}
 impl V for () {}
 
diff --git a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
index 1695e474de9..a7c469fccaa 100644
--- a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
+++ b/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Trait {}
+pub trait Trait {
+    fn dummy(&self) { }
+}
 
 pub struct Foo<T:Trait> {
     pub x: T,
diff --git a/src/test/auxiliary/trait_impl_conflict.rs b/src/test/auxiliary/trait_impl_conflict.rs
index 990bc216049..0982efbdbf4 100644
--- a/src/test/auxiliary/trait_impl_conflict.rs
+++ b/src/test/auxiliary/trait_impl_conflict.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
+pub trait Foo : ::std::marker::MarkerTrait {
 }
 
 impl Foo for int {
diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs
index 22e0d3168ca..56fb40bc0a4 100644
--- a/src/test/auxiliary/use_from_trait_xc.rs
+++ b/src/test/auxiliary/use_from_trait_xc.rs
@@ -11,7 +11,7 @@
 pub use self::sub::{Bar, Baz};
 
 pub trait Trait {
-    fn foo();
+    fn foo(&self);
 }
 
 struct Foo;
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 621f5ec9660..edd1b8255cc 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,8 +16,12 @@
 #![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 {
+pub trait Sized : PhantomFn<Self> {
     // Empty.
 }
 
diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs
index 95a68dd6698..b7a16c68a34 100644
--- a/src/test/compile-fail/associated-types-coherence-failure.rs
+++ b/src/test/compile-fail/associated-types-coherence-failure.rs
@@ -11,9 +11,10 @@
 // Test that coherence detects overlap when some of the types in the
 // impls are projections of associated type. Issue #20624.
 
+use std::marker::PhantomData;
 use std::ops::Deref;
 
-pub struct Cow<'a, B: ?Sized>;
+pub struct Cow<'a, B: ?Sized>(PhantomData<(&'a (),B)>);
 
 /// Trait for moving into a `Cow`
 pub trait IntoCow<'a, B: ?Sized> {
diff --git a/src/test/compile-fail/associated-types-eq-expr-path.rs b/src/test/compile-fail/associated-types-eq-expr-path.rs
index 9baa7f1ad5a..c48f9972ebc 100644
--- a/src/test/compile-fail/associated-types-eq-expr-path.rs
+++ b/src/test/compile-fail/associated-types-eq-expr-path.rs
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type A;
     fn bar() -> isize;
 }
diff --git a/src/test/compile-fail/associated-types-issue-17359.rs b/src/test/compile-fail/associated-types-issue-17359.rs
index fa09ae793bf..625f4cdb8ef 100644
--- a/src/test/compile-fail/associated-types-issue-17359.rs
+++ b/src/test/compile-fail/associated-types-issue-17359.rs
@@ -11,7 +11,7 @@
 // Test that we do not ICE when an impl is missing an associated type (and that we report
 // a useful error, of course).
 
-trait Trait {
+trait Trait : ::std::marker::MarkerTrait {
     type Type;
 }
 
diff --git a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
index 9436f825de8..5632f148da6 100644
--- a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
+++ b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type X;
     type Y;
 }
diff --git a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
index a3f2850b294..2b84c38f80b 100644
--- a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
+++ b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs
@@ -11,7 +11,7 @@
 // Check that we get an error when you use `<Self as Get>::Value` in
 // the trait definition but `Self` does not, in fact, implement `Get`.
 
-trait Get {
+trait Get : ::std::marker::MarkerTrait {
     type Value;
 }
 
diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs
index 51a37b517dd..b9a62ff4e41 100644
--- a/src/test/compile-fail/associated-types-path-2.rs
+++ b/src/test/compile-fail/associated-types-path-2.rs
@@ -12,6 +12,8 @@
 
 pub trait Foo {
     type A;
+
+    fn dummy(&self) { }
 }
 
 impl Foo for i32 {
diff --git a/src/test/compile-fail/associated-types-unconstrained.rs b/src/test/compile-fail/associated-types-unconstrained.rs
index aecbf217a5b..8832028f9ab 100644
--- a/src/test/compile-fail/associated-types-unconstrained.rs
+++ b/src/test/compile-fail/associated-types-unconstrained.rs
@@ -10,7 +10,7 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     type A;
     fn bar() -> isize;
 }
diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs
index c91849ca53e..3e02a11c378 100644
--- a/src/test/compile-fail/bad-mid-path-type-params.rs
+++ b/src/test/compile-fail/bad-mid-path-type-params.rs
@@ -10,13 +10,6 @@
 
 // ignore-tidy-linelength
 
-#![feature(no_std)]
-#![no_std]
-#![feature(lang_items)]
-
-#[lang="sized"]
-pub trait Sized {}
-
 struct S<T> {
     contents: T,
 }
diff --git a/src/test/compile-fail/bad-sized.rs b/src/test/compile-fail/bad-sized.rs
index 69be6414e4c..1944acbe1f3 100644
--- a/src/test/compile-fail/bad-sized.rs
+++ b/src/test/compile-fail/bad-sized.rs
@@ -12,7 +12,7 @@
 
 use std::cell::RefCell;
 
-trait Trait {}
+trait Trait : ::std::marker::MarkerTrait {}
 
 pub fn main() {
     let x: Vec<Trait + Sized> = Vec::new();
diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
index 27d97d18c94..d4decb71349 100644
--- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-implemented.rs
@@ -10,6 +10,7 @@
 
 use std::fmt::Show;
 use std::default::Default;
+use std::marker::MarkerTrait;
 
 // Test that two blanket impls conflict (at least without negative
 // bounds).  After all, some other crate could implement Even or Odd
@@ -19,9 +20,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even { }
+trait Even : MarkerTrait { }
 
-trait Odd { }
+trait Odd : MarkerTrait { }
 
 impl Even for isize { }
 
diff --git a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
index 0f233b78c72..b1ee1762b6e 100644
--- a/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
+++ b/src/test/compile-fail/coherence-blanket-conflicts-with-blanket-unimplemented.rs
@@ -19,9 +19,9 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-trait Even { }
+trait Even : ::std::marker::MarkerTrait { }
 
-trait Odd { }
+trait Odd : ::std::marker::MarkerTrait { }
 
 impl<T:Even> MyTrait for T { //~ ERROR E0119
     fn get(&self) -> usize { 0 }
diff --git a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
index c9dfb8201a9..a225f6cf473 100644
--- a/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
+++ b/src/test/compile-fail/coherence-conflicting-negative-trait-impl.rs
@@ -10,18 +10,18 @@
 
 #![feature(optin_builtin_traits)]
 
-trait MyTrait {}
+trait MyTrait : ::std::marker::MarkerTrait {}
 
-struct TestType<T>;
+struct TestType<T>(::std::marker::PhantomData<T>);
 
-unsafe impl<T: MyTrait> Send for TestType<T> {}
+unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
 //~^ ERROR conflicting implementations for trait `core::marker::Send`
 //~^^ ERROR conflicting implementations for trait `core::marker::Send`
 
 impl<T: MyTrait> !Send for TestType<T> {}
 //~^ ERROR conflicting implementations for trait `core::marker::Send`
 
-unsafe impl<T> Send for TestType<T> {}
+unsafe impl<T:'static> Send for TestType<T> {}
 //~^ ERROR error: conflicting implementations for trait `core::marker::Send`
 
 impl !Send for TestType<i32> {}
diff --git a/src/test/compile-fail/coherence-subtyping.rs b/src/test/compile-fail/coherence-subtyping.rs
new file mode 100644
index 00000000000..897cb083f84
--- /dev/null
+++ b/src/test/compile-fail/coherence-subtyping.rs
@@ -0,0 +1,50 @@
+// 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.
+
+// Test that two distinct impls which match subtypes of one another
+// yield coherence errors (or not) depending on the variance.
+
+trait Contravariant {
+    fn foo(&self) { }
+}
+
+impl Contravariant for for<'a,'b> fn(&'a u8, &'b u8) {
+    //~^ ERROR E0119
+}
+
+impl Contravariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+trait Covariant {
+    fn foo(&self) { }
+}
+
+impl Covariant for for<'a,'b> fn(&'a u8, &'b u8) {
+    //~^ ERROR E0119
+}
+
+impl Covariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+trait Invariant {
+    fn foo(&self) -> Self { }
+}
+
+impl Invariant for for<'a,'b> fn(&'a u8, &'b u8) {
+}
+
+impl Invariant for for<'a> fn(&'a u8, &'a u8) {
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs
index 86b7a8c8918..c97a9950d78 100644
--- a/src/test/compile-fail/cross-borrow-trait.rs
+++ b/src/test/compile-fail/cross-borrow-trait.rs
@@ -14,7 +14,7 @@
 #![feature(box_syntax)]
 
 struct Foo;
-trait Trait {}
+trait Trait : ::std::marker::MarkerTrait {}
 impl Trait for Foo {}
 
 pub fn main() {
diff --git a/src/test/compile-fail/destructure-trait-ref.rs b/src/test/compile-fail/destructure-trait-ref.rs
index f2e068cc4ff..d8b3f297a11 100644
--- a/src/test/compile-fail/destructure-trait-ref.rs
+++ b/src/test/compile-fail/destructure-trait-ref.rs
@@ -14,7 +14,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-trait T {}
+trait T : ::std::marker::MarkerTrait {}
 impl T for isize {}
 
 fn main() {
diff --git a/src/test/compile-fail/dst-bad-coerce1.rs b/src/test/compile-fail/dst-bad-coerce1.rs
index 2b96c5ebe12..6d9ba8d44c0 100644
--- a/src/test/compile-fail/dst-bad-coerce1.rs
+++ b/src/test/compile-fail/dst-bad-coerce1.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar : ::std::marker::MarkerTrait {}
 
 pub fn main() {
     // With a vec of isize.
diff --git a/src/test/compile-fail/dst-bad-coerce2.rs b/src/test/compile-fail/dst-bad-coerce2.rs
index 160197368d6..aa687266acb 100644
--- a/src/test/compile-fail/dst-bad-coerce2.rs
+++ b/src/test/compile-fail/dst-bad-coerce2.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar : ::std::marker::MarkerTrait {}
 impl Bar for Foo {}
 
 pub fn main() {
diff --git a/src/test/compile-fail/dst-bad-coerce3.rs b/src/test/compile-fail/dst-bad-coerce3.rs
index 347a2d2ecbe..46b89e1122a 100644
--- a/src/test/compile-fail/dst-bad-coerce3.rs
+++ b/src/test/compile-fail/dst-bad-coerce3.rs
@@ -15,7 +15,7 @@ struct Fat<T: ?Sized> {
 }
 
 struct Foo;
-trait Bar {}
+trait Bar : ::std::marker::MarkerTrait {}
 impl Bar for Foo {}
 
 fn baz<'a>() {
diff --git a/src/test/compile-fail/dst-bad-coercions.rs b/src/test/compile-fail/dst-bad-coercions.rs
index b30eada162b..8ec1034bc4d 100644
--- a/src/test/compile-fail/dst-bad-coercions.rs
+++ b/src/test/compile-fail/dst-bad-coercions.rs
@@ -10,8 +10,10 @@
 
 // Test implicit coercions involving DSTs and raw pointers.
 
+use std::marker::MarkerTrait;
+
 struct S;
-trait T {}
+trait T : MarkerTrait {}
 impl T for S {}
 
 struct Foo<T: ?Sized> {
diff --git a/src/test/compile-fail/dst-object-from-unsized-type.rs b/src/test/compile-fail/dst-object-from-unsized-type.rs
index 87ff4291f50..a1f0dda671e 100644
--- a/src/test/compile-fail/dst-object-from-unsized-type.rs
+++ b/src/test/compile-fail/dst-object-from-unsized-type.rs
@@ -10,7 +10,7 @@
 
 // Test that we cannot create objects from unsized types.
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
 impl Foo for str {}
 
 fn test1<T: ?Sized + Foo>(t: &T) {
diff --git a/src/test/compile-fail/exclusive-drop-and-copy.rs b/src/test/compile-fail/exclusive-drop-and-copy.rs
index 17453bc677f..f47f14d5879 100644
--- a/src/test/compile-fail/exclusive-drop-and-copy.rs
+++ b/src/test/compile-fail/exclusive-drop-and-copy.rs
@@ -20,7 +20,7 @@ impl Drop for Foo {
 }
 
 #[derive(Copy)] //~ ERROR the trait `Copy` may not be implemented
-struct Bar<T>;
+struct Bar<T>(::std::marker::PhantomData<T>);
 
 #[unsafe_destructor]
 impl<T> Drop for Bar<T> {
diff --git a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
index 02f09749d61..9fea5e609d1 100644
--- a/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-less-params-with-defaults.rs
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<A, B, C = (A, B)>;
+use std::marker;
+
+struct Foo<A, B, C = (A, B)>(
+    marker::PhantomData<(A,B,C)>);
 
 impl<A, B, C = (A, B)> Foo<A, B, C> {
-    fn new() -> Foo<A, B, C> {Foo}
+    fn new() -> Foo<A, B, C> {Foo(marker::PhantomData)}
 }
 
 fn main() {
diff --git a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
index d88da2625c1..73c19aa012d 100644
--- a/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-impl-more-params-with-defaults.rs
@@ -8,12 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 impl<T, A = Heap> Vec<T, A> {
-    fn new() -> Vec<T, A> {Vec}
+    fn new() -> Vec<T, A> {Vec(marker::PhantomData)}
 }
 
 fn main() {
diff --git a/src/test/compile-fail/generic-lifetime-trait-impl.rs b/src/test/compile-fail/generic-lifetime-trait-impl.rs
index fc54002820e..9b9f09f4777 100644
--- a/src/test/compile-fail/generic-lifetime-trait-impl.rs
+++ b/src/test/compile-fail/generic-lifetime-trait-impl.rs
@@ -16,9 +16,12 @@
 //
 // Regression test for issue #16218.
 
-trait Bar<'a> {}
+trait Bar<'a> {
+    fn dummy(&'a self);
+}
 
 trait Foo<'a> {
+    fn dummy(&'a self) { }
     fn bar<'b, T: Bar<'b>>(self) -> &'b str;
 }
 
diff --git a/src/test/compile-fail/generic-type-less-params-with-defaults.rs b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
index f25d8f99b8d..37737fda474 100644
--- a/src/test/compile-fail/generic-type-less-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-type-less-params-with-defaults.rs
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 fn main() {
     let _: Vec; //~ ERROR wrong number of type arguments: expected at least 1, found 0
diff --git a/src/test/compile-fail/generic-type-more-params-with-defaults.rs b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
index 19d303488ac..ad7e4f190c5 100644
--- a/src/test/compile-fail/generic-type-more-params-with-defaults.rs
+++ b/src/test/compile-fail/generic-type-more-params-with-defaults.rs
@@ -8,9 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Heap;
 
-struct Vec<T, A = Heap>;
+struct Vec<T, A = Heap>(
+    marker::PhantomData<(T,A)>);
 
 fn main() {
     let _: Vec<isize, Heap, bool>;
diff --git a/src/test/compile-fail/generic-type-params-name-repr.rs b/src/test/compile-fail/generic-type-params-name-repr.rs
index 3e34344d78b..a452cd35f94 100644
--- a/src/test/compile-fail/generic-type-params-name-repr.rs
+++ b/src/test/compile-fail/generic-type-params-name-repr.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct A;
 struct B;
 struct C;
-struct Foo<T = A, U = B, V = C>;
+struct Foo<T = A, U = B, V = C>(marker::PhantomData<(T,U,V)>);
 
-struct Hash<T>;
-struct HashMap<K, V, H = Hash<K>>;
+struct Hash<T>(marker::PhantomData<T>);
+struct HashMap<K, V, H = Hash<K>>(marker::PhantomData<(K,V,H)>);
 
 fn main() {
     // Ensure that the printed type doesn't include the default type params...
diff --git a/src/test/compile-fail/issue-11515.rs b/src/test/compile-fail/issue-11515.rs
index f0089b0ae5b..4ff574e939d 100644
--- a/src/test/compile-fail/issue-11515.rs
+++ b/src/test/compile-fail/issue-11515.rs
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-struct Test<'s> {
+struct Test {
     func: Box<FnMut()+'static>
 }
 
diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs
index ea0d880f4a1..dc697e4784f 100644
--- a/src/test/compile-fail/issue-13853-2.rs
+++ b/src/test/compile-fail/issue-13853-2.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait FromStructReader<'a> { }
+use std::marker::PhantomFn;
+
+trait FromStructReader<'a> : PhantomFn<(Self,&'a ())> { }
 trait ResponseHook {
      fn get<'a, T: FromStructReader<'a>>(&'a self);
 }
diff --git a/src/test/compile-fail/issue-13853-3.rs b/src/test/compile-fail/issue-13853-3.rs
index f10c47b594e..7ca158c3e32 100644
--- a/src/test/compile-fail/issue-13853-3.rs
+++ b/src/test/compile-fail/issue-13853-3.rs
@@ -10,6 +10,8 @@
 
 #![crate_type = "lib"]
 
+use std::marker::PhantomData;
+
 enum NodeContents<'a> {
     Children(Vec<Node<'a>>),
 }
@@ -22,11 +24,12 @@ impl<'a> Drop for NodeContents<'a> {
 
 struct Node<'a> {
     contents: NodeContents<'a>,
+    marker: PhantomData<&'a ()>,
 }
 
 impl<'a> Node<'a> {
     fn noName(contents: NodeContents<'a>) -> Node<'a> {
-        Node{  contents: contents,}
+        Node { contents: contents, marker: PhantomData }
     }
 }
 
diff --git a/src/test/compile-fail/issue-13853.rs b/src/test/compile-fail/issue-13853.rs
index 251da2c6b3e..cd3f337c4ab 100644
--- a/src/test/compile-fail/issue-13853.rs
+++ b/src/test/compile-fail/issue-13853.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Node {
+use std::marker::MarkerTrait;
+
+trait Node : MarkerTrait {
     fn zomg();
 }
 
diff --git a/src/test/compile-fail/issue-14285.rs b/src/test/compile-fail/issue-14285.rs
index cbf4412a81d..3a5df9e805b 100644
--- a/src/test/compile-fail/issue-14285.rs
+++ b/src/test/compile-fail/issue-14285.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 struct A;
 
diff --git a/src/test/compile-fail/issue-14853.rs b/src/test/compile-fail/issue-14853.rs
index 51deb99a4f2..0b846651acf 100644
--- a/src/test/compile-fail/issue-14853.rs
+++ b/src/test/compile-fail/issue-14853.rs
@@ -9,8 +9,9 @@
 // except according to those terms.
 
 use std::fmt::Debug;
+use std::marker::MarkerTrait;
 
-trait Str {}
+trait Str : MarkerTrait {}
 
 trait Something {
     fn yay<T: Debug>(_: Option<Self>, thing: &[T]);
diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs
index 814b885e3aa..a213234b89b 100644
--- a/src/test/compile-fail/issue-16747.rs
+++ b/src/test/compile-fail/issue-16747.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait ListItem<'a> {
+use std::marker::MarkerTrait;
+
+trait ListItem<'a> : MarkerTrait {
     fn list_name() -> &'a str;
 }
 
diff --git a/src/test/compile-fail/issue-17431-4.rs b/src/test/compile-fail/issue-17431-4.rs
index 1e27f025564..22aaa796ad0 100644
--- a/src/test/compile-fail/issue-17431-4.rs
+++ b/src/test/compile-fail/issue-17431-4.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T> { foo: Option<Option<Foo<T>>> }
+use std::marker;
+
+struct Foo<T> { foo: Option<Option<Foo<T>>>, marker: marker::PhantomData<T> }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 
 impl<T> Foo<T> { fn bar(&self) {} }
diff --git a/src/test/compile-fail/issue-17431-5.rs b/src/test/compile-fail/issue-17431-5.rs
index d22d79ecaa5..cc9cc2e3c03 100644
--- a/src/test/compile-fail/issue-17431-5.rs
+++ b/src/test/compile-fail/issue-17431-5.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 struct Foo { foo: Bar<Foo> }
-struct Bar<T> { x: Bar<Foo> }
+struct Bar<T> { x: Bar<Foo> , marker: marker::PhantomData<T> }
 //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable
 
 impl Foo { fn foo(&self) {} }
diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs
index e037ba92b4a..5781cb74117 100644
--- a/src/test/compile-fail/issue-17551.rs
+++ b/src/test/compile-fail/issue-17551.rs
@@ -10,9 +10,11 @@
 
 #![feature(unboxed_closures)]
 
-struct B<T>;
+use std::marker;
+
+struct B<T>(marker::PhantomData<T>);
 
 fn main() {
-    let foo = B; //~ ERROR: unable to infer enough type information
+    let foo = B(marker::PhantomData); //~ ERROR unable to infer enough type information
     let closure = || foo;
 }
diff --git a/src/test/compile-fail/issue-17904-2.rs b/src/test/compile-fail/issue-17904-2.rs
new file mode 100644
index 00000000000..a33ec23a16a
--- /dev/null
+++ b/src/test/compile-fail/issue-17904-2.rs
@@ -0,0 +1,16 @@
+// 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 <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.
+
+// Test that we can parse a unit struct with a where clause, even if
+// it leads to a error later on since `T` is unused.
+
+struct Foo<T> where T: Copy; //~ ERROR parameter `T` is never used
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-18107.rs b/src/test/compile-fail/issue-18107.rs
index 91689988f58..d5fb22bdebd 100644
--- a/src/test/compile-fail/issue-18107.rs
+++ b/src/test/compile-fail/issue-18107.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
 
-
-pub trait AbstractRenderer {}
+pub trait AbstractRenderer : MarkerTrait {}
 
 fn _create_render(_: &()) ->
     AbstractRenderer
diff --git a/src/test/compile-fail/issue-18611.rs b/src/test/compile-fail/issue-18611.rs
index a662e9ca98e..e81a576fa63 100644
--- a/src/test/compile-fail/issue-18611.rs
+++ b/src/test/compile-fail/issue-18611.rs
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
+
 fn add_state(op: <isize as HasState>::State) {
 //~^ ERROR the trait `HasState` is not implemented for the type `isize`
 }
 
-trait HasState {
+trait HasState : MarkerTrait {
     type State;
 }
 
diff --git a/src/test/compile-fail/issue-18783.rs b/src/test/compile-fail/issue-18783.rs
index 5ddf06add9d..13908bda9d8 100644
--- a/src/test/compile-fail/issue-18783.rs
+++ b/src/test/compile-fail/issue-18783.rs
@@ -26,6 +26,7 @@ fn ufcs() {
 
     Push::push(&c, box || y = 0);
     Push::push(&c, box || y = 0);
+//~^ ERROR cannot borrow `y` as mutable more than once at a time
 }
 
 trait Push<'c> {
diff --git a/src/test/compile-fail/issue-18819.rs b/src/test/compile-fail/issue-18819.rs
index 3a9de741043..951d78410b8 100644
--- a/src/test/compile-fail/issue-18819.rs
+++ b/src/test/compile-fail/issue-18819.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     type Item;
 }
 
diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs
index 14601e67a77..77aba7335bd 100644
--- a/src/test/compile-fail/issue-19660.rs
+++ b/src/test/compile-fail/issue-19660.rs
@@ -13,8 +13,12 @@
 #![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 {}
+trait Sized : PhantomFn<Self> {}
 
 #[start]
 fn main(_: int, _: *const *const u8) -> int {
diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs
index 00607f85034..aed395d17ea 100644
--- a/src/test/compile-fail/issue-2063.rs
+++ b/src/test/compile-fail/issue-2063.rs
@@ -12,10 +12,11 @@
 // cause compiler to loop.  Note that no instances
 // of such a type could ever be constructed.
 
+use std::marker::MarkerTrait;
 
 struct t(Box<t>); //~ ERROR this type cannot be instantiated
 
-trait to_str_2 {
+trait to_str_2 : MarkerTrait {
     fn my_to_string() -> String;
 }
 
diff --git a/src/test/compile-fail/issue-20831-debruijn.rs b/src/test/compile-fail/issue-20831-debruijn.rs
index aaf45f27398..5b623ac377b 100644
--- a/src/test/compile-fail/issue-20831-debruijn.rs
+++ b/src/test/compile-fail/issue-20831-debruijn.rs
@@ -13,10 +13,11 @@
 // below. Note that changing to a named lifetime made the problem go
 // away.
 
-use std::ops::{Shl, Shr};
 use std::cell::RefCell;
+use std::marker::MarkerTrait;
+use std::ops::{Shl, Shr};
 
-pub trait Subscriber {
+pub trait Subscriber : MarkerTrait {
     type Input;
 }
 
diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs
index 31796e5e20c..24cc0099b89 100644
--- a/src/test/compile-fail/issue-2611-4.rs
+++ b/src/test/compile-fail/issue-2611-4.rs
@@ -12,7 +12,7 @@
 // than the trait method it's implementing
 
 trait A {
-  fn b<C,D>(x: C) -> C;
+  fn b<C,D>(&self, x: C) -> C;
 }
 
 struct E {
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-    fn b<F: Sync, G>(_x: F) -> F { panic!() }
+    fn b<F: Sync, G>(&self, _x: F) -> F { panic!() }
     //~^ ERROR `F : core::marker::Sync` appears on the impl method
 }
 
diff --git a/src/test/compile-fail/issue-3008-3.rs b/src/test/compile-fail/issue-3008-3.rs
index a338a01690d..af6cee1f107 100644
--- a/src/test/compile-fail/issue-3008-3.rs
+++ b/src/test/compile-fail/issue-3008-3.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 enum E1 { V1(E2<E1>), }
-enum E2<T> { V2(E2<E1>), }
+enum E2<T> { V2(E2<E1>, marker::PhantomData<T>), }
 //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable
 
 impl E1 { fn foo(&self) {} }
diff --git a/src/test/compile-fail/issue-4972.rs b/src/test/compile-fail/issue-4972.rs
index 9a398796d2a..f384dba7c9e 100644
--- a/src/test/compile-fail/issue-4972.rs
+++ b/src/test/compile-fail/issue-4972.rs
@@ -11,7 +11,9 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 
-trait MyTrait { }
+trait MyTrait {
+    fn dummy(&self) {}
+}
 
 pub enum TraitWrapper {
     A(Box<MyTrait+'static>),
diff --git a/src/test/compile-fail/issue-5035-2.rs b/src/test/compile-fail/issue-5035-2.rs
index 9e324cdd61e..d316b44794a 100644
--- a/src/test/compile-fail/issue-5035-2.rs
+++ b/src/test/compile-fail/issue-5035-2.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait I {}
+use std::marker::MarkerTrait;
+
+trait I : MarkerTrait {}
 type K = I+'static;
 
 fn foo(_x: K) {} //~ ERROR: the trait `core::marker::Sized` is not implemented
diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs
index cf98f1572e5..eccbc789660 100644
--- a/src/test/compile-fail/issue-5543.rs
+++ b/src/test/compile-fail/issue-5543.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo {}
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {}
 impl Foo for u8 {}
 
 fn main() {
diff --git a/src/test/compile-fail/issue-5883.rs b/src/test/compile-fail/issue-5883.rs
index 9ff957b6e6d..b0db9906195 100644
--- a/src/test/compile-fail/issue-5883.rs
+++ b/src/test/compile-fail/issue-5883.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+use std::marker::MarkerTrait;
+
+trait A : MarkerTrait {}
 
 struct Struct {
     r: A+'static
@@ -20,6 +22,6 @@ fn new_struct(r: A+'static)
     Struct { r: r }
 }
 
-trait Curve {}
+trait Curve : MarkerTrait {}
 enum E {X(Curve+'static)}
 fn main() {}
diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs
index efa3100360b..0bf9a3c2d48 100644
--- a/src/test/compile-fail/issue-6458.rs
+++ b/src/test/compile-fail/issue-6458.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub struct TypeWithState<State>;
+use std::marker;
+
+pub struct TypeWithState<State>(marker::PhantomData<State>);
 pub struct MyState;
 
 pub fn foo<State>(_: TypeWithState<State>) {}
 
 pub fn bar() {
-   foo(TypeWithState);  //~ ERROR type annotations required
+   foo(TypeWithState(marker::PhantomData));  //~ ERROR type annotations required
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-7575.rs b/src/test/compile-fail/issue-7575.rs
index 9e6000c050a..b6643f43952 100644
--- a/src/test/compile-fail/issue-7575.rs
+++ b/src/test/compile-fail/issue-7575.rs
@@ -10,12 +10,14 @@
 
 // Test the mechanism for warning about possible missing `self` declarations.
 
+use std::marker::MarkerTrait;
+
 trait CtxtFn {
     fn f8(self, usize) -> usize;
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
-trait OtherTrait {
+trait OtherTrait : MarkerTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -24,7 +26,7 @@ trait OtherTrait {
 // declaration to match against, so we wind up prisizeing it as a
 // candidate. This seems not unreasonable -- perhaps the user meant to
 // implement it, after all.
-trait UnusedTrait {
+trait UnusedTrait : MarkerTrait {
     fn f9(usize) -> usize; //~ NOTE candidate
 }
 
@@ -52,7 +54,7 @@ impl Myisize {
     }
 }
 
-trait ManyImplTrait {
+trait ManyImplTrait : MarkerTrait {
     fn is_str() -> bool { //~ NOTE candidate
         false
     }
diff --git a/src/test/compile-fail/issue-8727.rs b/src/test/compile-fail/issue-8727.rs
index d1a86d334cb..72da6dcaa6c 100644
--- a/src/test/compile-fail/issue-8727.rs
+++ b/src/test/compile-fail/issue-8727.rs
@@ -13,16 +13,12 @@
 // Verify the compiler fails with an error on infinite function
 // recursions.
 
-struct Data(Box<Option<Data>>);
-
-fn generic<T>( _ : Vec<(Data,T)> ) {
-    let rec : Vec<(Data,(bool,T))> = Vec::new();
-    generic( rec );
+fn generic<T>() {
+    generic::<Option<T>>();
 }
 
 
 fn main () {
     // Use generic<T> at least once to trigger instantiation.
-    let input : Vec<(Data,())> = Vec::new();
-    generic(input);
+    generic::<i32>();
 }
diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs
index 56f83d93008..74e372e41eb 100644
--- a/src/test/compile-fail/kindck-copy.rs
+++ b/src/test/compile-fail/kindck-copy.rs
@@ -10,12 +10,12 @@
 
 // Test which of the builtin types are considered POD.
 
-
+use std::marker::MarkerTrait;
 use std::rc::Rc;
 
 fn assert_copy<T:Copy>() { }
 
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 #[derive(Copy)]
 struct MyStruct {
diff --git a/src/test/compile-fail/kindck-impl-type-params-2.rs b/src/test/compile-fail/kindck-impl-type-params-2.rs
index 2731be7308a..b575144f637 100644
--- a/src/test/compile-fail/kindck-impl-type-params-2.rs
+++ b/src/test/compile-fail/kindck-impl-type-params-2.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
 }
 
 impl<T:Copy> Foo for T {
diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs
index d5276efa8be..dffc8fa2abd 100644
--- a/src/test/compile-fail/kindck-impl-type-params.rs
+++ b/src/test/compile-fail/kindck-impl-type-params.rs
@@ -13,40 +13,44 @@
 
 #![feature(box_syntax)]
 
-struct S<T>;
+use std::marker;
 
-trait Gettable<T> {}
+struct S<T>(marker::PhantomData<T>);
+
+trait Gettable<T> {
+    fn get(&self) -> T { panic!() }
+}
 
 impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
 
 fn f<T>(val: T) {
-    let t: S<T> = S;
+    let t: S<T> = S(marker::PhantomData);
     let a = &t as &Gettable<T>;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn g<T>(val: T) {
-    let t: S<T> = S;
+    let t: S<T> = S(marker::PhantomData);
     let a: &Gettable<T> = &t;
     //~^ ERROR the trait `core::marker::Send` is not implemented
     //~^^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn foo<'a>() {
-    let t: S<&'a isize> = S;
+    let t: S<&'a isize> = S(marker::PhantomData);
     let a = &t as &Gettable<&'a isize>;
-    //~^ ERROR the type `&'a isize` does not fulfill the required lifetime
+    //~^ ERROR cannot infer
 }
 
 fn foo2<'a>() {
-    let t: Box<S<String>> = box S;
+    let t: Box<S<String>> = box S(marker::PhantomData);
     let a = t as Box<Gettable<String>>;
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
 
 fn foo3<'a>() {
-    let t: Box<S<String>> = box S;
+    let t: Box<S<String>> = box S(marker::PhantomData);
     let a: Box<Gettable<String>> = t;
     //~^ ERROR the trait `core::marker::Copy` is not implemented
 }
diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs
index 570f7ad7fe3..0c68401bb2b 100644
--- a/src/test/compile-fail/kindck-send-object.rs
+++ b/src/test/compile-fail/kindck-send-object.rs
@@ -12,8 +12,10 @@
 // in this file all test the "kind" violates detected during kindck.
 // See all `regions-bounded-by-send.rs`
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 trait Message : Send { }
 
 // careful with object types, who knows what they close over...
diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs
index 48d5215b708..f86eac8b16b 100644
--- a/src/test/compile-fail/kindck-send-object1.rs
+++ b/src/test/compile-fail/kindck-send-object1.rs
@@ -12,8 +12,10 @@
 // is broken into two parts because some errors occur in distinct
 // phases in the compiler. See kindck-send-object2.rs as well!
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send+'static>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs
index d3d166e2a69..08516e67318 100644
--- a/src/test/compile-fail/kindck-send-object2.rs
+++ b/src/test/compile-fail/kindck-send-object2.rs
@@ -10,8 +10,10 @@
 
 // Continue kindck-send-object1.rs.
 
+use std::marker::MarkerTrait;
+
 fn assert_send<T:Send>() { }
-trait Dummy { }
+trait Dummy : MarkerTrait { }
 
 fn test50() {
     assert_send::<&'static Dummy>(); //~ ERROR the trait `core::marker::Sync` is not implemented
diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
index 04c5b223cb8..66d8927ee51 100644
--- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
+++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs
@@ -10,7 +10,9 @@
 
 // ignore-tidy-linelength
 
-struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32 }
+use std::marker::PhantomData;
+
+struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> }
 fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
     (x.bar, &x.baz, &x.baz)
diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
index c60e321219b..a85776a938b 100644
--- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
+++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs
@@ -10,7 +10,9 @@
 
 // ignore-tidy-linelength
 
-struct Foo<'x> { bar: isize }
+use std::marker::PhantomData;
+
+struct Foo<'x> { bar: isize, marker: PhantomData<&'x ()> }
 fn foo1<'a>(x: &Foo) -> &'a isize {
 //~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a isize
     &x.bar //~ ERROR: cannot infer
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 3b96fd64fa2..73a58741bbb 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -47,20 +47,26 @@ fn foo3() {}
 /// dox
 pub trait A {
     /// dox
-    fn foo();
+    fn foo(&self);
     /// dox
-    fn foo_with_impl() {}
+    fn foo_with_impl(&self) {}
 }
+
 #[allow(missing_docs)]
 trait B {
-    fn foo();
-    fn foo_with_impl() {}
+    fn foo(&self);
+    fn foo_with_impl(&self) {}
 }
+
 pub trait C { //~ ERROR: missing documentation
-    fn foo(); //~ ERROR: missing documentation
-    fn foo_with_impl() {} //~ ERROR: missing documentation
+    fn foo(&self); //~ ERROR: missing documentation
+    fn foo_with_impl(&self) {} //~ ERROR: missing documentation
+}
+
+#[allow(missing_docs)]
+pub trait D {
+    fn dummy(&self) { }
 }
-#[allow(missing_docs)] pub trait D {}
 
 impl Foo {
     pub fn foo() {}
diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs
index 70d6b240985..9f58d5791cb 100644
--- a/src/test/compile-fail/lint-non-camel-case-types.rs
+++ b/src/test/compile-fail/lint-non-camel-case-types.rs
@@ -30,6 +30,7 @@ enum Foo5 {
 }
 
 trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
+    fn dummy(&self) { }
 }
 
 fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index f9cdfa4f7d6..88f2cbdea6d 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -341,7 +341,9 @@ mod this_crate {
 
     #[unstable(feature = "test_feature")]
     #[deprecated(since = "1.0.0")]
-    pub trait DeprecatedTrait {}
+    pub trait DeprecatedTrait {
+        fn dummy(&self) { }
+    }
 
     struct S;
 
diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs
index 8cf375f80fb..918b4ee209c 100644
--- a/src/test/compile-fail/lint-visible-private-types.rs
+++ b/src/test/compile-fail/lint-visible-private-types.rs
@@ -12,8 +12,10 @@
 #![allow(dead_code)]
 #![crate_type="lib"]
 
-struct Private<T>;
-pub struct Public<T>;
+use std::marker;
+
+struct Private<T>(marker::PhantomData<T>);
+pub struct Public<T>(marker::PhantomData<T>);
 
 impl Private<Public<isize>> {
     pub fn a(&self) -> Private<isize> { panic!() }
@@ -103,7 +105,7 @@ impl PrivTrait for (Private<isize>,) {
     fn bar(&self) -> Private<isize> { panic!() }
 }
 
-pub trait ParamTrait<T> {
+pub trait ParamTrait<T> : marker::MarkerTrait {
     fn foo() -> T;
 }
 
diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs
index a49339ecd7f..03d8d62e0b4 100644
--- a/src/test/compile-fail/liveness-use-after-send.rs
+++ b/src/test/compile-fail/liveness-use-after-send.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker;
+
 fn send<T:Send + std::fmt::Debug>(ch: _chan<T>, data: T) {
     println!("{:?}", ch);
     println!("{:?}", data);
@@ -15,7 +17,7 @@ fn send<T:Send + std::fmt::Debug>(ch: _chan<T>, data: T) {
 }
 
 #[derive(Debug)]
-struct _chan<T>(isize);
+struct _chan<T>(isize, marker::PhantomData<T>);
 
 // Tests that "log(debug, message);" is flagged as using
 // message after the send deinitializes it
diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs
index ba2205f5868..6e8719eeace 100644
--- a/src/test/compile-fail/map-types.rs
+++ b/src/test/compile-fail/map-types.rs
@@ -14,7 +14,10 @@ extern crate collections;
 
 use std::collections::HashMap;
 
-trait Map<K, V> {}
+trait Map<K, V>
+{
+    fn get(&self, k: K) -> V { panic!() }
+}
 
 impl<K, V> Map<K, V> for HashMap<K, V> {}
 
diff --git a/src/test/compile-fail/method-ambig-one-trait-coerce.rs b/src/test/compile-fail/method-ambig-one-trait-coerce.rs
deleted file mode 100644
index cb5da4bb547..00000000000
--- a/src/test/compile-fail/method-ambig-one-trait-coerce.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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 <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.
-
-// Test that when we pick a trait based on coercion, versus subtyping,
-// we consider all possible coercions equivalent and don't try to pick
-// a best one.
-
-trait Object { }
-
-trait foo {
-    fn foo(self) -> isize;
-}
-
-impl foo for Box<Object+'static> {
-    fn foo(self) -> isize {1}
-}
-
-impl foo for Box<Object+Send> {
-    fn foo(self) -> isize {2}
-}
-
-fn test1(x: Box<Object+Send+Sync>) {
-    // FIXME(#18737) -- we ought to consider this to be ambiguous,
-    // since we could coerce to either impl. However, what actually
-    // happens is that we consider both impls applicable because of
-    // incorrect subtyping relation. We then decide to call this a
-    // call to the `foo` trait, leading to the following error
-    // message.
-
-    x.foo(); //~ ERROR `foo` is not implemented
-}
-
-fn test2(x: Box<Object+Send>) {
-    // Not ambiguous because it is a precise match:
-    x.foo();
-}
-
-fn test3(x: Box<Object+'static>) {
-    // Not ambiguous because it is a precise match:
-    x.foo();
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/object-does-not-impl-trait.rs b/src/test/compile-fail/object-does-not-impl-trait.rs
index cfaf149a49c..607ab13d122 100644
--- a/src/test/compile-fail/object-does-not-impl-trait.rs
+++ b/src/test/compile-fail/object-does-not-impl-trait.rs
@@ -11,8 +11,9 @@
 // Test that an object type `Box<Foo>` is not considered to implement the
 // trait `Foo`. Issue #5087.
 
+use std::marker::MarkerTrait;
 
-trait Foo {}
+trait Foo : MarkerTrait {}
 fn take_foo<F:Foo>(f: F) {}
 fn take_object(f: Box<Foo>) { take_foo(f); }
 //~^ ERROR the trait `Foo` is not implemented
diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs
index c107c8d131d..23ddea4499a 100644
--- a/src/test/compile-fail/object-lifetime-default-mybox.rs
+++ b/src/test/compile-fail/object-lifetime-default-mybox.rs
@@ -37,7 +37,6 @@ fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
     a
       //~^ ERROR cannot infer
       //~| ERROR mismatched types
-      //~| ERROR mismatched types
 }
 
 fn main() {
diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs
index 6a010d49692..aae829ec7b5 100644
--- a/src/test/compile-fail/object-safety-no-static.rs
+++ b/src/test/compile-fail/object-safety-no-static.rs
@@ -11,7 +11,7 @@
 // Check that we correctly prevent users from making trait objects
 // from traits with static methods.
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
     fn foo();
 }
 
diff --git a/src/test/compile-fail/on-unimplemented-bad-anno.rs b/src/test/compile-fail/on-unimplemented-bad-anno.rs
index dda534cc489..7538b1c85e5 100644
--- a/src/test/compile-fail/on-unimplemented-bad-anno.rs
+++ b/src/test/compile-fail/on-unimplemented-bad-anno.rs
@@ -13,8 +13,12 @@
 
 #![allow(unused)]
 
+use std::marker;
+
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<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}`"]
 trait MyFromIterator<A> {
@@ -23,15 +27,21 @@ trait MyFromIterator<A> {
 }
 
 #[rustc_on_unimplemented] //~ ERROR this attribute must have a value
-trait BadAnnotation1 {}
+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> {}
+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> {}
+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 7b406afcf1f..2447d086422 100644
--- a/src/test/compile-fail/on-unimplemented.rs
+++ b/src/test/compile-fail/on-unimplemented.rs
@@ -11,8 +11,12 @@
 
 #![feature(on_unimplemented)]
 
+use std::marker;
+
 #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
-trait Foo<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/orphan-check-diagnostics.rs b/src/test/compile-fail/orphan-check-diagnostics.rs
index ff5c101b917..8201565c331 100644
--- a/src/test/compile-fail/orphan-check-diagnostics.rs
+++ b/src/test/compile-fail/orphan-check-diagnostics.rs
@@ -15,7 +15,7 @@ extern crate orphan_check_diagnostics;
 
 use orphan_check_diagnostics::RemoteTrait;
 
-trait LocalTrait {}
+trait LocalTrait { fn dummy(&self) { } }
 
 impl<T> RemoteTrait for T where T: LocalTrait {}
 //~^ ERROR type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/compile-fail/priv-in-bad-locations.rs b/src/test/compile-fail/priv-in-bad-locations.rs
index db649ed0cc6..43d112b8aa0 100644
--- a/src/test/compile-fail/priv-in-bad-locations.rs
+++ b/src/test/compile-fail/priv-in-bad-locations.rs
@@ -14,7 +14,7 @@ pub extern {
 }
 
 trait A {
-    fn foo() {}
+    fn foo(&self) {}
 }
 
 struct B;
@@ -22,7 +22,7 @@ struct B;
 pub impl B {} //~ ERROR: unnecessary visibility
 
 pub impl A for B { //~ ERROR: unnecessary visibility
-    pub fn foo() {} //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {} //~ ERROR: unnecessary visibility
 }
 
 pub fn main() {}
diff --git a/src/test/compile-fail/privacy-ns2.rs b/src/test/compile-fail/privacy-ns2.rs
index 7fe0574ab7d..67bb566ea68 100644
--- a/src/test/compile-fail/privacy-ns2.rs
+++ b/src/test/compile-fail/privacy-ns2.rs
@@ -17,7 +17,9 @@
 
 // public type, private value
 pub mod foo1 {
-    pub trait Bar {
+    use std::marker::MarkerTrait;
+
+    pub trait Bar : MarkerTrait {
     }
     pub struct Baz;
 
@@ -39,7 +41,7 @@ fn test_list1() {
 
 // private type, public value
 pub mod foo2 {
-    trait Bar {
+    trait Bar : ::std::marker::MarkerTrait {
     }
     pub struct Baz;
 
@@ -60,7 +62,7 @@ fn test_list2() {
 
 // neither public
 pub mod foo3 {
-    trait Bar {
+    trait Bar : ::std::marker::MarkerTrait {
     }
     pub struct Baz;
 
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index 7ebbcc2809a..1ae79adbad7 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -11,11 +11,15 @@
 #![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 {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang="copy"]
-pub trait Copy {}
+pub trait Copy : PhantomFn<Self> {}
 
 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 bcb46663aa8..adce93af079 100644
--- a/src/test/compile-fail/privacy4.rs
+++ b/src/test/compile-fail/privacy4.rs
@@ -11,8 +11,12 @@
 #![feature(lang_items, start, no_std)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
-#[lang = "sized"] pub trait Sized {}
-#[lang="copy"] pub trait Copy {}
+#[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> {}
 
 // Test to make sure that private items imported through globs remain private
 // when  they're used.
diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
index 20cc624ab19..2da414befd8 100644
--- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs
+++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs
@@ -13,7 +13,7 @@
 
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo : ::std::marker::MarkerTrait {}
 impl<'a> Foo for &'a [u8] {}
 
 fn a(v: &[u8]) -> Box<Foo + 'static> {
diff --git a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
index f833361e3b5..f921eccef1f 100644
--- a/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
+++ b/src/test/compile-fail/regions-assoc-type-region-bound-in-trait-not-met.rs
@@ -11,7 +11,10 @@
 // Test that the compiler checks that arbitrary region bounds declared
 // in the trait must be satisfied on the impl. Issue #20890.
 
-trait Foo<'a> { type Value: 'a; }
+trait Foo<'a> {
+    type Value: 'a;
+    fn dummy(&'a self) { }
+}
 
 impl<'a> Foo<'a> for &'a i16 {
     // OK.
diff --git a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
index 0871d8b01f6..1cf83b8ac58 100644
--- a/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
+++ b/src/test/compile-fail/regions-assoc-type-static-bound-in-trait-not-met.rs
@@ -11,7 +11,10 @@
 // Test that the compiler checks that the 'static bound declared in
 // the trait must be satisfied on the impl. Issue #20890.
 
-trait Foo { type Value: 'static; }
+trait Foo {
+    type Value: 'static;
+    fn dummy(&self) { }
+}
 
 impl<'a> Foo for &'a i32 {
     //~^ ERROR cannot infer
diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
index a3c38dff6b0..278ccd3c119 100644
--- a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
+++ b/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
@@ -21,10 +21,9 @@ pub trait Foo<'a, 't> {
     fn has_bound<'b:'a>(self, b: Inv<'b>);
     fn wrong_bound1<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
     fn okay_bound<'b,'c,'d:'a+'b+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
-    fn another_bound<'x: 'a>(self, x: Inv<'x>);
+    fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
 }
 
-
 impl<'a, 't> Foo<'a, 't> for &'a isize {
     fn no_bound<'b:'a>(self, b: Inv<'b>) {
         //~^ ERROR lifetime parameters or bounds on method `no_bound` do not match
@@ -51,7 +50,7 @@ impl<'a, 't> Foo<'a, 't> for &'a isize {
     fn okay_bound<'b,'c,'e:'b+'c>(self, b: Inv<'b>, c: Inv<'c>, e: Inv<'e>) {
     }
 
-    fn another_bound<'x: 't>(self, x: Inv<'x>) {}
+    fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {}
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
index 74c2c6e584b..f13d8a60894 100644
--- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
+++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs
@@ -8,16 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
-#![no_std]
-
 // Check that explicit region bounds are allowed on the various
 // nominal types (but not on other types) and that they are type
 // checked.
 
-#[lang="sized"]
-trait Sized { }
-
 struct Inv<'a> { // invariant w/r/t 'a
     x: &'a mut &'a isize
 }
diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs
index 8a03f36972d..979c1e997d0 100644
--- a/src/test/compile-fail/regions-close-associated-type-into-object.rs
+++ b/src/test/compile-fail/regions-close-associated-type-into-object.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait X {}
+use std::marker::MarkerTrait;
+
+trait X : MarkerTrait {}
 
 trait Iter {
     type Item: X;
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 7a0e3cf4611..7bbce7dad53 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,13 +11,16 @@
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : ::std::marker::MarkerTrait {}
+
 impl<'a, T> X for B<'a, T> {}
 
-fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+fn f<'a, T:'static, U>(v: Box<A<T>+'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-2.rs b/src/test/compile-fail/regions-close-object-into-object-2.rs
index 7861fb95fef..6de49020a6f 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,10 +10,12 @@
 
 #![feature(box_syntax)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> { }
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 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 31354de2a27..e22d0c7d0a4 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,10 +11,12 @@
 #![feature(box_syntax)]
 #![allow(warnings)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> {}
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 impl<'a, T> X for B<'a, T> {}
 
 fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
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 c60975f97e1..147a575d38c 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,10 +10,12 @@
 
 #![feature(box_syntax)]
 
-trait A<T> {}
+use std::marker::PhantomFn;
+
+trait A<T> : PhantomFn<(Self,T)> {}
 struct B<'a, T>(&'a (A<T>+'a));
 
-trait X {}
+trait X : PhantomFn<Self> {}
 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/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs
new file mode 100644
index 00000000000..05c6c6d9f9e
--- /dev/null
+++ b/src/test/compile-fail/regions-close-object-into-object-5.rs
@@ -0,0 +1,32 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(box_syntax)]
+#![allow(warnings)]
+
+use std::marker::MarkerTrait;
+
+trait A<T>
+{
+    fn get(&self) -> T { panic!() }
+}
+
+struct B<'a, T>(&'a (A<T>+'a));
+
+trait X : MarkerTrait {}
+
+impl<'a, T> X for B<'a, T> {}
+
+fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
+    box B(&*v) as Box<X> //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
index 25b8137d29c..2341d2397c9 100644
--- a/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
+++ b/src/test/compile-fail/regions-close-over-borrowed-ref-in-obj.rs
@@ -10,7 +10,9 @@
 
 #![feature(box_syntax)]
 
-trait Foo { }
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait { }
 
 impl<'a> Foo for &'a isize { }
 
diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs
index 74b36958c92..9ad49a6703e 100644
--- a/src/test/compile-fail/regions-close-param-into-object.rs
+++ b/src/test/compile-fail/regions-close-param-into-object.rs
@@ -10,7 +10,7 @@
 
 #![feature(box_syntax)]
 
-trait X {}
+trait X : ::std::marker::MarkerTrait {}
 
 fn p1<T>(v: T) -> Box<X+'static>
     where T : X
diff --git a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
index 6c5e90a54de..b7ef19d1e3b 100644
--- a/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-contravariance-due-to-decl.rs
@@ -20,7 +20,7 @@ use std::marker;
 // Contravariant<'foo> <: Contravariant<'static> because
 // 'foo <= 'static
 struct Contravariant<'a> {
-    marker: marker::ContravariantLifetime<'a>
+    marker: marker::PhantomData<&'a()>
 }
 
 fn use_<'short,'long>(c: Contravariant<'short>,
diff --git a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
index d8e31fa1374..0d3d9dacbd6 100644
--- a/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-covariance-due-to-decl.rs
@@ -17,7 +17,7 @@
 use std::marker;
 
 struct Covariant<'a> {
-    marker: marker::CovariantLifetime<'a>
+    marker: marker::PhantomData<fn(&'a ())>
 }
 
 fn use_<'short,'long>(c: Covariant<'long>,
diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
index e88c96de9e4..8c191fbd5bb 100644
--- a/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
+++ b/src/test/compile-fail/regions-infer-invariance-due-to-decl.rs
@@ -11,7 +11,7 @@
 use std::marker;
 
 struct invariant<'a> {
-    marker: marker::InvariantLifetime<'a>
+    marker: marker::PhantomData<*mut &'a()>
 }
 
 fn to_same_lifetime<'r>(b_isize: invariant<'r>) {
diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs
index 7d252604883..1b749faf1b8 100644
--- a/src/test/compile-fail/required-lang-item.rs
+++ b/src/test/compile-fail/required-lang-item.rs
@@ -11,7 +11,11 @@
 #![feature(lang_items, no_std)]
 #![no_std]
 
-#[lang="sized"] pub trait Sized {}
+#[lang="phantom_fn"]
+pub trait PhantomFn<T:?Sized> { }
+impl<T:?Sized, U:?Sized> PhantomFn<T> for U { }
+
+#[lang="sized"] pub trait Sized : PhantomFn<Self> {}
 
 // error-pattern:requires `start` lang_item
 
diff --git a/src/test/compile-fail/shadowed-type-parameter.rs b/src/test/compile-fail/shadowed-type-parameter.rs
index 1a3d7821159..1f72db1e894 100644
--- a/src/test/compile-fail/shadowed-type-parameter.rs
+++ b/src/test/compile-fail/shadowed-type-parameter.rs
@@ -12,19 +12,21 @@
 
 #![feature(box_syntax)]
 
-struct Foo<T>;
+struct Foo<T>(T);
 
 impl<T> Foo<T> {
     fn shadow_in_method<T>(&self) {}
     //~^ ERROR type parameter `T` shadows another type parameter
 
     fn not_shadow_in_item<U>(&self) {
-        struct Bar<T, U>; // not a shadow, separate item
+        struct Bar<T, U>(T,U); // not a shadow, separate item
         fn foo<T, U>() {} // same
     }
 }
 
 trait Bar<T> {
+    fn dummy(&self) -> T;
+
     fn shadow_in_required<T>(&self);
     //~^ ERROR type parameter `T` shadows another type parameter
 
diff --git a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
index 1203d622348..3c1c3796a24 100644
--- a/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
+++ b/src/test/compile-fail/slightly-nice-generic-literal-messages.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T,U>(T);
+use std::marker;
+
+struct Foo<T,U>(T, marker::PhantomData<U>);
 
 fn main() {
-    match Foo(1.1) {
+    match Foo(1.1, marker::PhantomData) {
         1 => {}
     //~^ ERROR mismatched types
     //~| expected `Foo<_, _>`
diff --git a/src/test/compile-fail/staticness-mismatch.rs b/src/test/compile-fail/staticness-mismatch.rs
index bf4e46cace3..2dfc9b79ee2 100644
--- a/src/test/compile-fail/staticness-mismatch.rs
+++ b/src/test/compile-fail/staticness-mismatch.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 trait foo {
+    fn dummy(&self) { }
     fn bar();
 }
 
diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs
index a1fcab002e1..fff14414094 100644
--- a/src/test/compile-fail/trait-as-struct-constructor.rs
+++ b/src/test/compile-fail/trait-as-struct-constructor.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TraitNotAStruct { }
+trait TraitNotAStruct : ::std::marker::MarkerTrait { }
 
 fn main() {
     TraitNotAStruct{ value: 0 };
diff --git a/src/test/compile-fail/trait-bounds-cant-coerce.rs b/src/test/compile-fail/trait-bounds-cant-coerce.rs
index 79174552ae0..3129dceffbb 100644
--- a/src/test/compile-fail/trait-bounds-cant-coerce.rs
+++ b/src/test/compile-fail/trait-bounds-cant-coerce.rs
@@ -10,6 +10,7 @@
 
 
 trait Foo {
+    fn dummy(&self) { }
 }
 
 fn a(_x: Box<Foo+Send>) {
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 477bd4f5be9..34e06cc9365 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-1.rs
@@ -11,7 +11,10 @@
 // Make sure rustc checks the type parameter bounds in implementations of traits,
 // see #2687
 
-trait A {}
+use std::marker;
+
+trait A : marker::PhantomFn<Self> {
+}
 
 trait B: A {}
 
@@ -62,15 +65,16 @@ impl Foo for isize {
     //~^ ERROR the requirement `T : C` appears on the impl
 }
 
-
-trait Getter<T> { }
+trait Getter<T> {
+    fn get(&self) -> T { loop { } }
+}
 
 trait Trait {
-    fn method<G:Getter<isize>>();
+    fn method<G:Getter<isize>>(&self);
 }
 
 impl Trait for usize {
-    fn method<G: Getter<usize>>() {}
+    fn method<G: Getter<usize>>(&self) {}
     //~^ G : Getter<usize>` appears on the impl method but not on the corresponding trait method
 }
 
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 8ad19116e7b..284c4fac953 100644
--- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
+++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs
@@ -14,7 +14,9 @@ trait Iterator<A> {
     fn next(&mut self) -> Option<A>;
 }
 
-trait IteratorUtil<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/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
index 434d803d718..448b186f6a5 100644
--- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
+++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 trait Foo {
+    fn dummy(&self) { }
 }
 
 // This should emit the less confusing error, not the more confusing one.
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
index 118dfeb37c2..df44e847c50 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-locals.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait {
+    fn dummy(&self) { }
+}
 
 struct Foo<T:Trait> {
     x: T,
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
index d5369817e9a..18871d0d386 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums-static.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait {
+    fn dummy(&self) { }
+}
 
 struct Foo<T:Trait> {
     x: T,
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
index 490ee0e8ad6..8dfdb2f205d 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+use std::marker::MarkerTrait;
+
+trait Trait : MarkerTrait {}
 
 struct Foo<T:Trait> {
     x: T,
@@ -51,15 +53,15 @@ enum MoreBadness<V> {
     EvenMoreBadness(Bar<V>),
 }
 
-trait PolyTrait<T> {
-    fn whatever() {}
+trait PolyTrait<T>
+{
+    fn whatever(&self, t: T) {}
 }
 
 struct Struct;
 
 impl PolyTrait<Foo<usize>> for Struct {
 //~^ ERROR not implemented
-    fn whatever() {}
 }
 
 fn main() {
diff --git a/src/test/compile-fail/trait-bounds-sugar.rs b/src/test/compile-fail/trait-bounds-sugar.rs
index 3d264e681a3..e4058a0943a 100644
--- a/src/test/compile-fail/trait-bounds-sugar.rs
+++ b/src/test/compile-fail/trait-bounds-sugar.rs
@@ -10,8 +10,9 @@
 
 // Tests for "default" bounds inferred for traits with no bounds list.
 
+use std::marker::MarkerTrait;
 
-trait Foo {}
+trait Foo : MarkerTrait {}
 
 fn a(_x: Box<Foo+Send>) {
 }
diff --git a/src/test/compile-fail/trait-impl-1.rs b/src/test/compile-fail/trait-impl-1.rs
index dadcbd5bce7..2f4793b4d88 100644
--- a/src/test/compile-fail/trait-impl-1.rs
+++ b/src/test/compile-fail/trait-impl-1.rs
@@ -12,7 +12,9 @@
 // trait impl is only applied to a trait object, not concrete types which implement
 // the trait.
 
-trait T {}
+use std::marker::MarkerTrait;
+
+trait T : MarkerTrait {}
 
 impl<'a> T+'a {
     fn foo(&self) {}
diff --git a/src/test/compile-fail/trait-object-safety.rs b/src/test/compile-fail/trait-object-safety.rs
index 761bcd4968a..d45d13556e1 100644
--- a/src/test/compile-fail/trait-object-safety.rs
+++ b/src/test/compile-fail/trait-object-safety.rs
@@ -12,6 +12,7 @@
 
 trait Tr {
     fn foo();
+    fn bar(&self) { }
 }
 
 struct St;
diff --git a/src/test/compile-fail/trait-static-method-generic-inference.rs b/src/test/compile-fail/trait-static-method-generic-inference.rs
index 651f663fc99..0e357d9d4d5 100644
--- a/src/test/compile-fail/trait-static-method-generic-inference.rs
+++ b/src/test/compile-fail/trait-static-method-generic-inference.rs
@@ -16,6 +16,7 @@
 mod base {
     pub trait HasNew<T> {
         fn new() -> T;
+        fn dummy(&self) { }
     }
 
     pub struct Foo {
diff --git a/src/test/compile-fail/typeck-negative-impls-builtin.rs b/src/test/compile-fail/typeck-negative-impls-builtin.rs
index 9da79b11cf0..557fb2f4f88 100644
--- a/src/test/compile-fail/typeck-negative-impls-builtin.rs
+++ b/src/test/compile-fail/typeck-negative-impls-builtin.rs
@@ -12,7 +12,9 @@
 
 struct TestType;
 
-trait TestTrait {}
+trait TestTrait {
+    fn dummy(&self) { }
+}
 
 impl !TestTrait for TestType {}
 //~^ ERROR  negative impls are currently allowed just for `Send` and `Sync`
diff --git a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
index a34be63ba6b..1daea8f915b 100644
--- a/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
+++ b/src/test/compile-fail/typeck_type_placeholder_mismatch.rs
@@ -11,14 +11,16 @@
 // This test checks that genuine type errors with partial
 // type hints are understandable.
 
-struct Foo<T>;
-struct Bar<U>;
+use std::marker::PhantomData;
+
+struct Foo<T>(PhantomData<T>);
+struct Bar<U>(PhantomData<U>);
 
 pub fn main() {
 }
 
 fn test1() {
-    let x: Foo<_> = Bar::<usize>;
+    let x: Foo<_> = Bar::<usize>(PhantomData);
     //~^ ERROR mismatched types
     //~| expected `Foo<_>`
     //~| found `Bar<usize>`
@@ -28,7 +30,7 @@ fn test1() {
 }
 
 fn test2() {
-    let x: Foo<_> = Bar::<usize>;
+    let x: Foo<_> = Bar::<usize>(PhantomData);
     //~^ ERROR mismatched types
     //~| expected `Foo<_>`
     //~| found `Bar<usize>`
diff --git a/src/test/compile-fail/unboxed-closure-feature-gate.rs b/src/test/compile-fail/unboxed-closure-feature-gate.rs
index 3536244f011..74a6f869f63 100644
--- a/src/test/compile-fail/unboxed-closure-feature-gate.rs
+++ b/src/test/compile-fail/unboxed-closure-feature-gate.rs
@@ -11,8 +11,12 @@
 // Check that parenthetical notation is feature-gated except with the
 // `Fn` traits.
 
+use std::marker;
+
 trait Foo<A> {
     type Output;
+
+    fn dummy(&self, a: A) { }
 }
 
 fn main() {
diff --git a/src/test/compile-fail/unboxed-closure-sugar-default.rs b/src/test/compile-fail/unboxed-closure-sugar-default.rs
index 870377bc1ad..831db98941c 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-default.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-default.rs
@@ -19,7 +19,7 @@ trait Foo<T,V=T> {
     fn dummy(&self, t: T, v: V);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> { fn same_types(&self, x: &X) -> bool { true } }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
 
diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
index dc5576aee65..6d315c1b7a9 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs
@@ -16,12 +16,14 @@
 #![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> { }
+trait Eq<X: ?Sized> : PhantomFn<(Self,X)> { }
 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 d2f781bba11..bd3530e6e30 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
@@ -16,12 +16,14 @@
 #![feature(unboxed_closures)]
 #![allow(dead_code)]
 
+use std::marker;
+
 trait Foo<T> {
     type Output;
     fn dummy(&self, t: T);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> : marker::PhantomFn<(Self, X)> { }
 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-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs
index 75688e44e80..057b496bd43 100644
--- a/src/test/compile-fail/unboxed-closure-sugar-region.rs
+++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs
@@ -22,7 +22,7 @@ trait Foo<'a,T> {
     fn dummy(&'a self) -> &'a (T,Self::Output);
 }
 
-trait Eq<X: ?Sized> { }
+trait Eq<X: ?Sized> { fn is_of_eq_type(&self, x: &X) -> bool { true } }
 impl<X: ?Sized> Eq<X> for X { }
 fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
diff --git a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
index 215b2c6798e..713b64b1349 100644
--- a/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
+++ b/src/test/compile-fail/unboxed-closures-recursive-fn-using-fn-mut.rs
@@ -10,7 +10,7 @@
 
 #![feature(core,unboxed_closures)]
 
-use std::marker::CovariantType;
+use std::marker::PhantomData;
 
 // A erroneous variant of `run-pass/unboxed_closures-infer-recursive-fn.rs`
 // where we attempt to perform mutation in the recursive function. This fails to compile
@@ -18,12 +18,12 @@ use std::marker::CovariantType;
 
 struct YCombinator<F,A,R> {
     func: F,
-    marker: CovariantType<(A,R)>,
+    marker: PhantomData<(A,R)>,
 }
 
 impl<F,A,R> YCombinator<F,A,R> {
     fn new(f: F) -> YCombinator<F,A,R> {
-        YCombinator { func: f, marker: CovariantType }
+        YCombinator { func: f, marker: PhantomData }
     }
 }
 
diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs
index e3707292f24..964db6e9a45 100644
--- a/src/test/compile-fail/unnecessary-private.rs
+++ b/src/test/compile-fail/unnecessary-private.rs
@@ -13,10 +13,10 @@ fn main() {
     pub struct A; //~ ERROR: visibility has no effect
     pub enum B {} //~ ERROR: visibility has no effect
     pub trait C { //~ ERROR: visibility has no effect
-        pub fn foo() {} //~ ERROR: visibility has no effect
+        pub fn foo(&self) {} //~ ERROR: visibility has no effect
     }
     impl A {
-        pub fn foo() {} //~ ERROR: visibility has no effect
+        pub fn foo(&self) {} //~ ERROR: visibility has no effect
     }
 
     struct D {
diff --git a/src/test/compile-fail/unsized-inherent-impl-self-type.rs b/src/test/compile-fail/unsized-inherent-impl-self-type.rs
index 8740346a217..a03c76b12dd 100644
--- a/src/test/compile-fail/unsized-inherent-impl-self-type.rs
+++ b/src/test/compile-fail/unsized-inherent-impl-self-type.rs
@@ -12,7 +12,7 @@
 
 // impl - struct
 
-struct S5<Y>;
+struct S5<Y>(Y);
 
 impl<X: ?Sized> S5<X> { //~ ERROR not implemented
 }
diff --git a/src/test/compile-fail/unsized-trait-impl-self-type.rs b/src/test/compile-fail/unsized-trait-impl-self-type.rs
index 3dd55b0ba7d..08df1d9b7b8 100644
--- a/src/test/compile-fail/unsized-trait-impl-self-type.rs
+++ b/src/test/compile-fail/unsized-trait-impl-self-type.rs
@@ -12,9 +12,10 @@
 
 // impl - struct
 trait T3<Z: ?Sized> {
+    fn foo(&self, z: &Z);
 }
 
-struct S5<Y>;
+struct S5<Y>(Y);
 
 impl<X: ?Sized> T3<X> for S5<X> { //~ ERROR not implemented
 }
diff --git a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
index ac8043d6852..4723dfeaeb9 100644
--- a/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
+++ b/src/test/compile-fail/unsized-trait-impl-trait-arg.rs
@@ -12,8 +12,9 @@
 
 // impl - unbounded
 trait T2<Z> {
+    fn foo(&self, z: Z);
 }
-struct S4<Y: ?Sized>;
+struct S4<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized> T2<X> for S4<X> {
     //~^ ERROR `core::marker::Sized` is not implemented for the type `X`
 }
diff --git a/src/test/compile-fail/unsized3.rs b/src/test/compile-fail/unsized3.rs
index 4fc76c99c60..de1cbab82b2 100644
--- a/src/test/compile-fail/unsized3.rs
+++ b/src/test/compile-fail/unsized3.rs
@@ -10,6 +10,7 @@
 
 // Test sized-ness checking in substitution within fn bodies..
 
+use std::marker;
 
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
@@ -20,7 +21,9 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T {}
+trait T {
+    fn foo(&self) { }
+}
 fn f3<X: ?Sized + T>(x: &X) {
     f4::<X>(x);
     //~^ ERROR the trait `core::marker::Sized` is not implemented
diff --git a/src/test/compile-fail/unsized6.rs b/src/test/compile-fail/unsized6.rs
index 217d1f44d84..f31a6ffdc0d 100644
--- a/src/test/compile-fail/unsized6.rs
+++ b/src/test/compile-fail/unsized6.rs
@@ -10,8 +10,9 @@
 
 // Test `?Sized` local variables.
 
+use std::marker;
 
-trait T {}
+trait T : marker::MarkerTrait { }
 
 fn f1<X: ?Sized>(x: &X) {
     let _: X; // <-- this is OK, no bindings created, no initializer.
diff --git a/src/test/compile-fail/unsized7.rs b/src/test/compile-fail/unsized7.rs
index 6fc547c0b8e..6ea3d0720ee 100644
--- a/src/test/compile-fail/unsized7.rs
+++ b/src/test/compile-fail/unsized7.rs
@@ -10,13 +10,17 @@
 
 // Test sized-ness checking in substitution in impls.
 
-trait T {}
+use std::marker::MarkerTrait;
+
+trait T : MarkerTrait {}
 
 // I would like these to fail eventually.
 // impl - bounded
 trait T1<Z: T> {
+    fn dummy(&self) -> Z;
 }
-struct S3<Y: ?Sized>;
+
+struct S3<Y: ?Sized>(Box<Y>);
 impl<X: ?Sized + T> T1<X> for S3<X> {
     //~^ ERROR `core::marker::Sized` is not implemented for the type `X`
 }
diff --git a/src/test/compile-fail/unused-attr.rs b/src/test/compile-fail/unused-attr.rs
index 2d4bc0c857a..af242b96a84 100644
--- a/src/test/compile-fail/unused-attr.rs
+++ b/src/test/compile-fail/unused-attr.rs
@@ -52,9 +52,9 @@ struct Foo {
 #[foo] //~ ERROR unused attribute
 trait Baz {
     #[foo] //~ ERROR unused attribute
-    fn blah();
+    fn blah(&self);
     #[foo] //~ ERROR unused attribute
-    fn blah2() {}
+    fn blah2(&self) {}
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/useless-priv.rs b/src/test/compile-fail/useless-priv.rs
index d8531f4543d..b1120e54434 100644
--- a/src/test/compile-fail/useless-priv.rs
+++ b/src/test/compile-fail/useless-priv.rs
@@ -12,12 +12,14 @@ struct A { pub i: isize }
 pub enum C { pub Variant }      //~ ERROR: unnecessary `pub`
 
 pub trait E {
-    pub fn foo() {}             //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {}         //~ ERROR: unnecessary visibility
+}
+trait F {
+    pub fn foo(&self) {}     //~ ERROR: unnecessary visibility
 }
-trait F { pub fn foo() {} }     //~ ERROR: unnecessary visibility
 
 impl E for A {
-    pub fn foo() {}             //~ ERROR: unnecessary visibility
+    pub fn foo(&self) {}             //~ ERROR: unnecessary visibility
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/useless-priv2.rs b/src/test/compile-fail/useless-priv2.rs
index 7125a66b294..a404d09248f 100644
--- a/src/test/compile-fail/useless-priv2.rs
+++ b/src/test/compile-fail/useless-priv2.rs
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 pub trait E {
-    pub fn foo();               //~ ERROR: unnecessary visibility
+    pub fn foo(&self);               //~ ERROR: unnecessary visibility
+}
+trait F {
+    pub fn foo(&self);               //~ ERROR: unnecessary visibility
 }
-trait F { pub fn foo(); }       //~ ERROR: unnecessary visibility
 
 fn main() {}
diff --git a/src/test/compile-fail/variance-contravariant-arg-object.rs b/src/test/compile-fail/variance-contravariant-arg-object.rs
new file mode 100644
index 00000000000..3330e1d0d51
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-arg-object.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self, t: T);
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v
+}
+
+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
new file mode 100644
index 00000000000..caaad4014ad
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-arg-trait-match.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self, t: T);
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>()
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-contravariant-self-trait-match.rs b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
new file mode 100644
index 00000000000..013511ed517
--- /dev/null
+++ b/src/test/compile-fail/variance-contravariant-self-trait-match.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get(&self);
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'max G : Get
+{
+    impls_get::<&'min G>(); //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'min G : Get
+{
+    impls_get::<&'max G>();
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-arg-object.rs b/src/test/compile-fail/variance-covariant-arg-object.rs
new file mode 100644
index 00000000000..828c987c082
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-arg-object.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self) -> T;
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-arg-trait-match.rs b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
new file mode 100644
index 00000000000..17761b9c0b1
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-arg-trait-match.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self) -> T;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>()
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-covariant-self-trait-match.rs b/src/test/compile-fail/variance-covariant-self-trait-match.rs
new file mode 100644
index 00000000000..4e94a3eeb46
--- /dev/null
+++ b/src/test/compile-fail/variance-covariant-self-trait-match.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get() -> Self;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'max G : Get
+{
+    impls_get::<&'min G>();
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : 'max, &'min G : Get
+{
+    impls_get::<&'max G>(); //~ ERROR mismatched types
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-deprecated-markers.rs b/src/test/compile-fail/variance-deprecated-markers.rs
new file mode 100644
index 00000000000..8f9d24cb132
--- /dev/null
+++ b/src/test/compile-fail/variance-deprecated-markers.rs
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that the deprecated markers still have their old effect.
+
+#![feature(rustc_attrs)]
+
+use std::marker;
+
+#[rustc_variance]
+struct A<T>(marker::CovariantType<T>); //~ ERROR types=[[+];[];[]]
+
+#[rustc_variance]
+struct B<T>(marker::ContravariantType<T>); //~ ERROR types=[[-];[];[]]
+
+#[rustc_variance]
+struct C<T>(marker::InvariantType<T>); //~ ERROR types=[[o];[];[]]
+
+#[rustc_variance]
+struct D<'a>(marker::CovariantLifetime<'a>); //~ ERROR regions=[[+];[];[]]
+
+#[rustc_variance]
+struct E<'a>(marker::ContravariantLifetime<'a>); //~ ERROR regions=[[-];[];[]]
+
+#[rustc_variance]
+struct F<'a>(marker::InvariantLifetime<'a>); //~ ERROR regions=[[o];[];[]]
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-arg-object.rs b/src/test/compile-fail/variance-invariant-arg-object.rs
new file mode 100644
index 00000000000..9edb510b826
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-arg-object.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get<T> : 'static {
+    fn get(&self, t: T) -> T;
+}
+
+fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+                                -> Box<Get<&'min i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+                                   -> Box<Get<&'max i32>>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-arg-trait-match.rs b/src/test/compile-fail/variance-invariant-arg-trait-match.rs
new file mode 100644
index 00000000000..45fed0b083d
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-arg-trait-match.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get<T> {
+    fn get(&self, t: T) -> T;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'max i32>
+{
+    impls_get::<G,&'min i32>() //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, G : Get<&'min i32>
+{
+    impls_get::<G,&'max i32>() //~ ERROR mismatched types
+}
+
+fn impls_get<G,T>() where G : Get<T> { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-invariant-self-trait-match.rs b/src/test/compile-fail/variance-invariant-self-trait-match.rs
new file mode 100644
index 00000000000..b46cd302ae5
--- /dev/null
+++ b/src/test/compile-fail/variance-invariant-self-trait-match.rs
@@ -0,0 +1,31 @@
+// 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.
+
+#![allow(dead_code)]
+
+trait Get {
+    fn get(&self) -> Self;
+}
+
+fn get_min_from_max<'min, 'max, G>()
+    where 'max : 'min, &'max G : Get
+{
+    impls_get::<&'min G>(); //~ ERROR mismatched types
+}
+
+fn get_max_from_min<'min, 'max, G>()
+    where 'max : 'min, &'min G : Get
+{
+    impls_get::<&'max G>(); //~ ERROR mismatched types
+}
+
+fn impls_get<G>() where G : Get { }
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-issue-20533.rs b/src/test/compile-fail/variance-issue-20533.rs
new file mode 100644
index 00000000000..0254f56bd1a
--- /dev/null
+++ b/src/test/compile-fail/variance-issue-20533.rs
@@ -0,0 +1,54 @@
+// 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.
+
+// Regression test for issue #20533. At some point, only 1 out of the
+// 3 errors below were being reported.
+
+use std::marker::PhantomData;
+
+fn foo<'a, T>(_x: &'a T) -> PhantomData<&'a ()> {
+    PhantomData
+}
+
+struct Wrap<T>(T);
+
+fn bar<'a, T>(_x: &'a T) -> Wrap<PhantomData<&'a ()>> {
+    Wrap(PhantomData)
+}
+
+struct Baked<'a>(PhantomData<&'a ()>);
+
+fn baz<'a, T>(_x: &'a T) -> Baked<'a> {
+    Baked(PhantomData)
+}
+
+struct AffineU32(u32);
+
+fn main() {
+    {
+        let a = AffineU32(1_u32);
+        let x = foo(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+    {
+        let a = AffineU32(1_u32);
+        let x = bar(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+    {
+        let a = AffineU32(1_u32);
+        let x = baz(&a);
+        drop(a); //~ ERROR cannot move out of `a`
+        drop(x);
+    }
+}
+
diff --git a/src/test/compile-fail/variance-regions-direct.rs b/src/test/compile-fail/variance-regions-direct.rs
index d70305d1106..da4d6c75227 100644
--- a/src/test/compile-fail/variance-regions-direct.rs
+++ b/src/test/compile-fail/variance-regions-direct.rs
@@ -60,6 +60,7 @@ struct Test6<'a, 'b> { //~ ERROR regions=[[-, o];[];[]]
 
 #[rustc_variance]
 struct Test7<'a> { //~ ERROR regions=[[*];[];[]]
+    //~^ ERROR parameter `'a` is never used
     x: isize
 }
 
diff --git a/src/test/compile-fail/variance-regions-indirect.rs b/src/test/compile-fail/variance-regions-indirect.rs
index 4bb329d6304..9beb90d0b24 100644
--- a/src/test/compile-fail/variance-regions-indirect.rs
+++ b/src/test/compile-fail/variance-regions-indirect.rs
@@ -16,6 +16,7 @@
 
 #[rustc_variance]
 enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
+    //~^ ERROR parameter `'d` is never used
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
     Test8C(&'b mut &'c str),
@@ -23,16 +24,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR regions=[[+, -, o, *];[];[]]
 
 #[rustc_variance]
 struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR regions=[[*, o, -, +];[];[]]
+    //~^ ERROR parameter `'w` is never used
     f: Base<'z, 'y, 'x, 'w>
 }
 
 #[rustc_variance] // Combine - and + to yield o
 struct Derived2<'a, 'b:'a, 'c> { //~ ERROR regions=[[o, o, *];[];[]]
+    //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'a, 'b, 'c>
 }
 
 #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
 struct Derived3<'a:'b, 'b, 'c> { //~ ERROR regions=[[o, -, *];[];[]]
+    //~^ ERROR parameter `'c` is never used
     f: Base<'a, 'b, 'a, 'c>
 }
 
diff --git a/src/test/run-pass/regions-infer-bivariance.rs b/src/test/compile-fail/variance-regions-unused-direct.rs
index a3288e2e1b9..396e7765206 100644
--- a/src/test/run-pass/regions-infer-bivariance.rs
+++ b/src/test/compile-fail/variance-regions-unused-direct.rs
@@ -8,21 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Test that a type whose lifetime parameters is never used is
-// inferred to be bivariant.
+// Test that disallow lifetime parameters that are unused.
 
 use std::marker;
 
-struct Bivariant<'a>;
+struct Bivariant<'a>; //~ ERROR parameter `'a` is never used
 
-fn use1<'short,'long>(c: Bivariant<'short>,
-                      _where:Option<&'short &'long ()>) {
-    let _: Bivariant<'long> = c;
+struct Struct<'a, 'd> { //~ ERROR parameter `'d` is never used
+    field: &'a [i32]
 }
 
-fn use2<'short,'long>(c: Bivariant<'long>,
-                      _where:Option<&'short &'long ()>) {
-    let _: Bivariant<'short> = c;
+trait Trait<'a, 'd> { //~ ERROR parameter `'d` is never used
+    fn method(&'a self);
 }
 
-pub fn main() {}
+fn main() {}
diff --git a/src/test/run-pass/export-non-interference.rs b/src/test/compile-fail/variance-regions-unused-indirect.rs
index 94652e30fe6..2d234ed7b57 100644
--- a/src/test/run-pass/export-non-interference.rs
+++ b/src/test/compile-fail/variance-regions-unused-indirect.rs
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// Test that disallow lifetime parameters that are unused.
 
-enum list_cell<T> { cons(Box<list_cell<T>>), nil }
+enum Foo<'a> { //~ ERROR parameter `'a` is never used
+    Foo1(Bar<'a>)
+}
 
-pub fn main() { }
+enum Bar<'a> { //~ ERROR parameter `'a` is never used
+    Bar1(Foo<'a>)
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-trait-bounds.rs b/src/test/compile-fail/variance-trait-bounds.rs
new file mode 100644
index 00000000000..88b50058b65
--- /dev/null
+++ b/src/test/compile-fail/variance-trait-bounds.rs
@@ -0,0 +1,65 @@
+// 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 <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.
+
+#![deny(bivariance)]
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+// Check that bounds on type parameters (other than `Self`) do not
+// influence variance.
+
+#[rustc_variance]
+trait Getter<T> { //~ ERROR types=[[+];[-];[]]
+    fn get(&self) -> T;
+}
+
+#[rustc_variance]
+trait Setter<T> { //~ ERROR types=[[-];[-];[]]
+    fn get(&self, T);
+}
+
+#[rustc_variance]
+struct TestStruct<U,T:Setter<U>> { //~ ERROR types=[[+, +];[];[]]
+    t: T, u: U
+}
+
+#[rustc_variance]
+enum TestEnum<U,T:Setter<U>> {//~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    Foo(T)
+}
+
+#[rustc_variance]
+trait TestTrait<U,T:Setter<U>> { //~ ERROR types=[[-, +];[-];[]]
+    fn getter(&self, u: U) -> T;
+}
+
+#[rustc_variance]
+trait TestTrait2<U> : Getter<U> { //~ ERROR types=[[+];[-];[]]
+}
+
+#[rustc_variance]
+trait TestTrait3<U> { //~ ERROR types=[[-];[-];[]]
+    fn getter<T:Getter<U>>(&self);
+}
+
+#[rustc_variance]
+struct TestContraStruct<U,T:Setter<U>> { //~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    t: T
+}
+
+#[rustc_variance]
+struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR types=[[*, +];[];[]]
+    //~^ ERROR parameter `U` is never used
+    t: T
+}
+
+pub fn main() { }
diff --git a/src/test/compile-fail/variance-trait-object-bound.rs b/src/test/compile-fail/variance-trait-object-bound.rs
index 965b9430a5e..f0ca1edd563 100644
--- a/src/test/compile-fail/variance-trait-object-bound.rs
+++ b/src/test/compile-fail/variance-trait-object-bound.rs
@@ -18,7 +18,7 @@
 
 use std::mem;
 
-trait T { fn foo(); }
+trait T { fn foo(&self); }
 
 #[rustc_variance]
 struct TOption<'a> { //~ ERROR regions=[[-];[];[]]
diff --git a/src/test/compile-fail/variance-types-bounds.rs b/src/test/compile-fail/variance-types-bounds.rs
new file mode 100644
index 00000000000..d53e4cd7610
--- /dev/null
+++ b/src/test/compile-fail/variance-types-bounds.rs
@@ -0,0 +1,76 @@
+// 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 <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.
+
+// Test that we correctly infer variance for type parameters in
+// various types and traits.
+
+#![feature(rustc_attrs)]
+
+#[rustc_variance]
+struct TestImm<A, B> { //~ ERROR types=[[+, +];[];[]]
+    x: A,
+    y: B,
+}
+
+#[rustc_variance]
+struct TestMut<A, B:'static> { //~ ERROR types=[[+, o];[];[]]
+    x: A,
+    y: &'static mut B,
+}
+
+#[rustc_variance]
+struct TestIndirect<A:'static, B:'static> { //~ ERROR types=[[+, o];[];[]]
+    m: TestMut<A, B>
+}
+
+#[rustc_variance]
+struct TestIndirect2<A:'static, B:'static> { //~ ERROR types=[[o, o];[];[]]
+    n: TestMut<A, B>,
+    m: TestMut<B, A>
+}
+
+#[rustc_variance]
+trait Getter<A> { //~ ERROR types=[[+];[-];[]]
+    fn get(&self) -> A;
+}
+
+#[rustc_variance]
+trait Setter<A> { //~ ERROR types=[[-];[o];[]]
+    fn set(&mut self, a: A);
+}
+
+#[rustc_variance]
+trait GetterSetter<A> { //~ ERROR types=[[o];[o];[]]
+    fn get(&self) -> A;
+    fn set(&mut self, a: A);
+}
+
+#[rustc_variance]
+trait GetterInTypeBound<A> { //~ ERROR types=[[-];[-];[]]
+    // 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
+    // contravariant, and the Getter is covariant w/r/t A, yielding an
+    // overall contravariant result.
+    fn do_it<T:Getter<A>>(&self);
+}
+
+#[rustc_variance]
+trait SetterInTypeBound<A> { //~ ERROR types=[[+];[-];[]]
+    fn do_it<T:Setter<A>>(&self);
+}
+
+#[rustc_variance]
+struct TestObject<A, R> { //~ ERROR types=[[-, +];[];[]]
+    n: Box<Setter<A>+Send>,
+    m: Box<Getter<R>+Send>,
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-types.rs b/src/test/compile-fail/variance-types.rs
new file mode 100644
index 00000000000..e407ebe345a
--- /dev/null
+++ b/src/test/compile-fail/variance-types.rs
@@ -0,0 +1,52 @@
+// 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 <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.
+
+#![deny(bivariance)]
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+// Check that a type parameter which is only used in a trait bound is
+// not considered bivariant.
+
+#[rustc_variance]
+struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR types=[[o, o];[];[]], regions=[[-];[];[]]
+    t: &'a mut (A,B)
+}
+
+#[rustc_variance]
+struct InvariantCell<A> { //~ ERROR types=[[o];[];[]]
+    t: Cell<A>
+}
+
+#[rustc_variance]
+struct InvariantIndirect<A> { //~ ERROR types=[[o];[];[]]
+    t: InvariantCell<A>
+}
+
+#[rustc_variance]
+struct Covariant<A> { //~ ERROR types=[[+];[];[]]
+    t: A, u: fn() -> A
+}
+
+#[rustc_variance]
+struct Contravariant<A> { //~ ERROR types=[[-];[];[]]
+    t: fn(A)
+}
+
+#[rustc_variance]
+enum Enum<A,B,C> { //~ ERROR types=[[+, -, o];[];[]]
+    Foo(Covariant<A>),
+    Bar(Contravariant<B>),
+    Zed(Covariant<C>,Contravariant<C>)
+}
+
+pub fn main() { }
diff --git a/src/test/compile-fail/variance-unused-region-param.rs b/src/test/compile-fail/variance-unused-region-param.rs
new file mode 100644
index 00000000000..5f504226370
--- /dev/null
+++ b/src/test/compile-fail/variance-unused-region-param.rs
@@ -0,0 +1,17 @@
+// 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 <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.
+
+// Test that we report an error for unused type parameters in types.
+
+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
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-unused-type-param.rs b/src/test/compile-fail/variance-unused-type-param.rs
new file mode 100644
index 00000000000..2e867ec3c93
--- /dev/null
+++ b/src/test/compile-fail/variance-unused-type-param.rs
@@ -0,0 +1,36 @@
+// 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 <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.
+
+#![allow(dead_code)]
+
+// Test that we report an error for unused type parameters in types and traits,
+// and that we offer a helpful suggestion.
+
+struct SomeStruct<A> { x: u32 }
+//~^ ERROR parameter `A` is never used
+//~| HELP PhantomData
+
+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
+//~| HELP PhantomData
+    Cons(Box<ListCell<T>>),
+    Nil
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/variance-use-contravariant-struct-1.rs b/src/test/compile-fail/variance-use-contravariant-struct-1.rs
new file mode 100644
index 00000000000..d2fd2978750
--- /dev/null
+++ b/src/test/compile-fail/variance-use-contravariant-struct-1.rs
@@ -0,0 +1,26 @@
+// 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.
+
+// Test various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(fn(T));
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/variance-use-contravariant-struct-2.rs b/src/test/compile-fail/variance-use-contravariant-struct-2.rs
new file mode 100644
index 00000000000..b38fd0e9ffc
--- /dev/null
+++ b/src/test/compile-fail/variance-use-contravariant-struct-2.rs
@@ -0,0 +1,27 @@
+// 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.
+
+// Test various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(fn(T));
+
+fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v
+}
+
+#[rustc_error]
+fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/variance-use-covariant-struct-1.rs b/src/test/compile-fail/variance-use-covariant-struct-1.rs
new file mode 100644
index 00000000000..2631cfc05e8
--- /dev/null
+++ b/src/test/compile-fail/variance-use-covariant-struct-1.rs
@@ -0,0 +1,23 @@
+// 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.
+
+// Test that a covariant struct does not permit the lifetime of a
+// reference to be enlarged.
+
+struct SomeStruct<T>(T);
+
+fn foo<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/variance-use-covariant-struct-2.rs b/src/test/compile-fail/variance-use-covariant-struct-2.rs
new file mode 100644
index 00000000000..d8e1a5f5f1c
--- /dev/null
+++ b/src/test/compile-fail/variance-use-covariant-struct-2.rs
@@ -0,0 +1,26 @@
+// 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.
+
+// Test that a covariant struct permits the lifetime of a reference to
+// be shortened.
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(T);
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v
+}
+
+#[rustc_error] fn main() { } //~ ERROR compilation successful
diff --git a/src/test/compile-fail/variance-use-invariant-struct-1.rs b/src/test/compile-fail/variance-use-invariant-struct-1.rs
new file mode 100644
index 00000000000..c89436b2094
--- /dev/null
+++ b/src/test/compile-fail/variance-use-invariant-struct-1.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// Test various uses of structs with distint variances to make sure
+// they permit lifetimes to be approximated as expected.
+
+#![feature(rustc_attrs)]
+
+struct SomeStruct<T>(*mut T);
+
+fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+                  -> SomeStruct<&'min ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+                  -> SomeStruct<&'max ()>
+    where 'max : 'min
+{
+    v //~ ERROR mismatched types
+}
+
+#[rustc_error]
+fn main() { }
diff --git a/src/test/compile-fail/visible-private-types-generics.rs b/src/test/compile-fail/visible-private-types-generics.rs
index 7ff18f8e088..1f2205b5c71 100644
--- a/src/test/compile-fail/visible-private-types-generics.rs
+++ b/src/test/compile-fail/visible-private-types-generics.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 pub fn f<
     T
diff --git a/src/test/compile-fail/visible-private-types-supertrait.rs b/src/test/compile-fail/visible-private-types-supertrait.rs
index dc6d446154a..9d9eae4a075 100644
--- a/src/test/compile-fail/visible-private-types-supertrait.rs
+++ b/src/test/compile-fail/visible-private-types-supertrait.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {}
+trait Foo {
+    fn dummy(&self) { }
+}
 
 pub trait Bar : Foo {} //~ ERROR private trait in exported type
 
diff --git a/src/test/compile-fail/where-clause-method-substituion.rs b/src/test/compile-fail/where-clause-method-substituion.rs
index a5108f005dc..bf614e6eb51 100644
--- a/src/test/compile-fail/where-clause-method-substituion.rs
+++ b/src/test/compile-fail/where-clause-method-substituion.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo<T> {}
+trait Foo<T> {
+    fn dummy(&self, t: T) { }
+}
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
diff --git a/src/test/compile-fail/where-clauses-not-parameter.rs b/src/test/compile-fail/where-clauses-not-parameter.rs
index 313ae273c07..7968cc37090 100644
--- a/src/test/compile-fail/where-clauses-not-parameter.rs
+++ b/src/test/compile-fail/where-clauses-not-parameter.rs
@@ -21,7 +21,7 @@ fn test2() -> bool where Option<isize> : Eq {}
 
 #[derive(PartialEq)]
 //~^ ERROR cannot bound type `isize`, where clause bounds
-enum Foo<T> where isize : Eq { MkFoo }
+enum Foo<T> where isize : Eq { MkFoo(T) }
 //~^ ERROR cannot bound type `isize`, where clause bounds
 
 fn test3<T: Eq>() -> bool where Option<Foo<T>> : Eq {}
@@ -31,7 +31,7 @@ fn test4() -> bool where Option<Foo<isize>> : Eq {}
 
 trait Baz<T> where isize : Eq {
     //~^ ERROR cannot bound type `isize`, where clause bounds may only
-    fn baz() where String : Eq; //~ ERROR cannot bound type `collections::string::String`
+    fn baz(&self, t: T) where String : Eq; //~ ERROR cannot bound type `collections::string::String`
     //~^ ERROR cannot bound type `isize`, where clause
 }
 
diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs
index a592484f1a4..bf26fc23d3c 100644
--- a/src/test/debuginfo/type-names.rs
+++ b/src/test/debuginfo/type-names.rs
@@ -177,10 +177,11 @@
 #![omit_gdb_pretty_printer_section]
 
 use self::Enum1::{Variant1_1, Variant1_2};
+use std::marker::PhantomData;
 use std::ptr;
 
 struct Struct1;
-struct GenericStruct<T1, T2>;
+struct GenericStruct<T1, T2>(PhantomData<(T1,T2)>);
 
 enum Enum1 {
     Variant1_1,
@@ -207,8 +208,8 @@ mod Mod1 {
     }
 }
 
-trait Trait1 { }
-trait Trait2<T1, T2> { }
+trait Trait1 { fn dummy(&self) { } }
+trait Trait2<T1, T2> { fn dummy(&self, _: T1, _:T2) { } }
 
 impl Trait1 for isize {}
 impl<T1, T2> Trait2<T1, T2> for isize {}
@@ -240,8 +241,10 @@ fn main() {
 
     // Structs
     let simple_struct = Struct1;
-    let generic_struct1: GenericStruct<Mod1::Struct2, Mod1::Mod2::Struct3> = GenericStruct;
-    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> = GenericStruct;
+    let generic_struct1: GenericStruct<Mod1::Struct2, Mod1::Mod2::Struct3> =
+        GenericStruct(PhantomData);
+    let generic_struct2: GenericStruct<Struct1, extern "fastcall" fn(isize) -> usize> =
+        GenericStruct(PhantomData);
     let mod_struct = Mod1::Struct2;
 
     // Enums
@@ -262,10 +265,10 @@ fn main() {
 
     // References
     let ref1 = (&Struct1, 0i32);
-    let ref2 = (&GenericStruct::<char, Struct1>, 0i32);
+    let ref2 = (&GenericStruct::<char, Struct1>(PhantomData), 0i32);
 
     let mut mut_struct1 = Struct1;
-    let mut mut_generic_struct = GenericStruct::<Mod1::Enum2, f64>;
+    let mut mut_generic_struct = GenericStruct::<Mod1::Enum2, f64>(PhantomData);
     let mut_ref1 = (&mut mut_struct1, 0i32);
     let mut_ref2 = (&mut mut_generic_struct, 0i32);
 
diff --git a/src/test/pretty/empty-impl.rs b/src/test/pretty/empty-impl.rs
index f22f1b40952..f5205de5c1f 100644
--- a/src/test/pretty/empty-impl.rs
+++ b/src/test/pretty/empty-impl.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait X { }
+trait X { fn dummy(&self) { } }
 impl X for uint { }
 
-trait Y { }
+trait Y { fn dummy(&self) { } }
 impl Y for uint { }
diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs
index e27a3365a41..9e1f2aa8bfe 100644
--- a/src/test/pretty/path-type-bounds.rs
+++ b/src/test/pretty/path-type-bounds.rs
@@ -11,7 +11,9 @@
 // pp-exact
 
 
-trait Tr { }
+trait Tr {
+    fn dummy(&self) { }
+}
 impl Tr for int { }
 
 fn foo<'a>(x: Box<Tr+ Sync + 'a>) -> Box<Tr+ Sync + 'a> { x }
diff --git a/src/test/run-fail/bug-811.rs b/src/test/run-fail/bug-811.rs
index e46564f8076..4ad81197286 100644
--- a/src/test/run-fail/bug-811.rs
+++ b/src/test/run-fail/bug-811.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 // error-pattern:quux
+
+use std::marker::PhantomData;
+
 fn test00_start(ch: chan_t<int>, message: int) { send(ch, message); }
 
 type task_id = int;
@@ -17,6 +20,7 @@ type port_id = int;
 struct chan_t<T> {
     task: task_id,
     port: port_id,
+    marker: PhantomData<*mut T>,
 }
 
 fn send<T:Send>(_ch: chan_t<T>, _data: T) { panic!(); }
diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/run-make/rustdoc-json/foo.rs
index d57a7164cdb..3bd56c14193 100644
--- a/src/test/run-make/rustdoc-json/foo.rs
+++ b/src/test/run-make/rustdoc-json/foo.rs
@@ -21,5 +21,5 @@ pub mod bar {
     }
 
     /// *wow*
-    pub trait Doge { }
+    pub trait Doge { fn dummy(&self) { } }
 }
diff --git a/src/test/run-make/rustdoc-negative-impl/foo.rs b/src/test/run-make/rustdoc-negative-impl/foo.rs
index b5fcbf46c5c..6c56bcc9be6 100644
--- a/src/test/run-make/rustdoc-negative-impl/foo.rs
+++ b/src/test/run-make/rustdoc-negative-impl/foo.rs
@@ -13,7 +13,7 @@
 // @matches foo/struct.Alpha.html '//pre' "pub struct Alpha"
 pub struct Alpha;
 // @matches foo/struct.Bravo.html '//pre' "pub struct Bravo<B>"
-pub struct Bravo<B>;
+pub struct Bravo<B>(B);
 
 // @matches foo/struct.Alpha.html '//*[@class="impl"]//code' "impl !Send for Alpha"
 impl !Send for Alpha {}
diff --git a/src/test/run-make/rustdoc-search-index/index.rs b/src/test/run-make/rustdoc-search-index/index.rs
index dd68f2d6f1d..42469a21f22 100644
--- a/src/test/run-make/rustdoc-search-index/index.rs
+++ b/src/test/run-make/rustdoc-search-index/index.rs
@@ -21,6 +21,6 @@ mod private {
     }
 
     pub trait PrivateTrait {
-        fn trait_method() {} // @!has - priv_method
+        fn trait_method(&self) {} // @!has - priv_method
     }
 }
diff --git a/src/test/run-make/rustdoc-smoke/foo.rs b/src/test/run-make/rustdoc-smoke/foo.rs
index 0438c9aba35..f6b73021beb 100644
--- a/src/test/run-make/rustdoc-smoke/foo.rs
+++ b/src/test/run-make/rustdoc-smoke/foo.rs
@@ -26,7 +26,7 @@ pub mod bar {
 
     /// *wow*
     // @has foo/bar/trait.Doge.html
-    pub trait Doge { }
+    pub trait Doge { fn dummy(&self) { } }
 
     // @has foo/bar/struct.Foo.html
     pub struct Foo { x: int, y: uint }
diff --git a/src/test/run-make/rustdoc-viewpath-self/foo.rs b/src/test/run-make/rustdoc-viewpath-self/foo.rs
index da8f7393023..6fd47d84c30 100644
--- a/src/test/run-make/rustdoc-viewpath-self/foo.rs
+++ b/src/test/run-make/rustdoc-viewpath-self/foo.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub mod io {
-    pub trait Reader { }
+    pub trait Reader { fn dummy(&self) { } }
 }
 
 pub enum Maybe<A> {
diff --git a/src/test/run-make/rustdoc-where/foo.rs b/src/test/run-make/rustdoc-where/foo.rs
index 68fde60564e..91a7e1c9fd4 100644
--- a/src/test/run-make/rustdoc-where/foo.rs
+++ b/src/test/run-make/rustdoc-where/foo.rs
@@ -8,30 +8,33 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait MyTrait {}
+pub trait MyTrait { fn dummy(&self) { } }
 
 // @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A> where A: MyTrait"
-pub struct Alpha<A> where A: MyTrait;
+pub struct Alpha<A>(A) where A: MyTrait;
 // @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B> where B: MyTrait"
-pub trait Bravo<B> where B: MyTrait {}
+pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
 // @has foo/fn.charlie.html '//pre' "pub fn charlie<C>() where C: MyTrait"
 pub fn charlie<C>() where C: MyTrait {}
 
-pub struct Delta<D>;
+pub struct Delta<D>(D);
+
 // @has foo/struct.Delta.html '//*[@class="impl"]//code' \
 //          "impl<D> Delta<D> where D: MyTrait"
 impl<D> Delta<D> where D: MyTrait {
     pub fn delta() {}
 }
 
-pub struct Echo<E>;
+pub struct Echo<E>(E);
+
 // @has foo/struct.Echo.html '//*[@class="impl"]//code' \
 //          "impl<E> MyTrait for Echo<E> where E: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \
 //          "impl<E> MyTrait for Echo<E> where E: MyTrait"
 impl<E> MyTrait for Echo<E> where E: MyTrait {}
 
-pub enum Foxtrot<F> {}
+pub enum Foxtrot<F> { Foxtrot1(F) }
+
 // @has foo/enum.Foxtrot.html '//*[@class="impl"]//code' \
 //          "impl<F> MyTrait for Foxtrot<F> where F: MyTrait"
 // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//code' \
diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs
index fbbecfbf2a6..b6366ad6737 100644
--- a/src/test/run-make/save-analysis/foo.rs
+++ b/src/test/run-make/save-analysis/foo.rs
@@ -99,6 +99,7 @@ struct some_fields {
 type SF = some_fields;
 
 trait SuperTrait {
+    fn dummy(&self) { }
 }
 
 trait SomeTrait: SuperTrait {
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs
index 834a2adf01f..f418d5d1fb7 100755
--- a/src/test/run-make/simd-ffi/simd.rs
+++ b/src/test/run-make/simd-ffi/simd.rs
@@ -70,10 +70,14 @@ pub fn bar(a: i32x4, b: i32x4) -> i32x4 {
 }
 
 #[lang = "sized"]
-trait Sized {}
+pub trait Sized : PhantomFn<Self> {}
 
 #[lang = "copy"]
-trait 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 { }
 
 mod core {
     pub mod marker {
diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs
index 1e0570c95ac..e1f36ecda53 100644
--- a/src/test/run-make/symbols-are-reasonable/lib.rs
+++ b/src/test/run-make/symbols-are-reasonable/lib.rs
@@ -11,7 +11,7 @@
 pub static X: &'static str = "foobarbaz";
 pub static Y: &'static [u8] = include_bytes!("lib.rs");
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 impl Foo for uint {}
 
 pub fn dummy() {
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index 365fc039a4e..acda8705b19 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -11,11 +11,15 @@
 #![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 { }
+trait Copy : PhantomFn<Self> { }
 
 #[lang="sized"]
-trait Sized { }
+trait Sized : PhantomFn<Self>  { }
 
 #[lang="start"]
 fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 }
diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
index 195055f12d1..aecec44f6fd 100644
--- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
+++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
@@ -25,7 +25,7 @@ impl Drop for Foo {
 }
 
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 impl Trait for Foo {}
 
 pub fn main() {
diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs
index 47e2a18a999..c49a684de94 100644
--- a/src/test/run-pass-valgrind/dst-dtor-1.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-1.rs
@@ -19,7 +19,7 @@ impl Drop for Foo {
     }
 }
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 impl Trait for Foo {}
 
 struct Fat<T: ?Sized> {
diff --git a/src/test/run-pass/associated-types-basic.rs b/src/test/run-pass/associated-types-basic.rs
index 3314b613201..f5521f7da85 100644
--- a/src/test/run-pass/associated-types-basic.rs
+++ b/src/test/run-pass/associated-types-basic.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     type T;
 }
 
diff --git a/src/test/run-pass/associated-types-conditional-dispatch.rs b/src/test/run-pass/associated-types-conditional-dispatch.rs
index f21b7183d70..aa65b0ed10b 100644
--- a/src/test/run-pass/associated-types-conditional-dispatch.rs
+++ b/src/test/run-pass/associated-types-conditional-dispatch.rs
@@ -14,6 +14,7 @@
 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
 // with all the others.
 
+use std::marker::PhantomData;
 use std::ops::Deref;
 
 pub trait MyEq<U: ?Sized=Self> {
@@ -41,7 +42,8 @@ impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs
 }
 
 struct DerefWithHelper<H, T> {
-    pub helper: H
+    pub helper: H,
+    pub marker: PhantomData<T>,
 }
 
 trait Helper<T> {
@@ -63,7 +65,8 @@ impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
 }
 
 pub fn check<T: MyEq>(x: T, y: T) -> bool {
-    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
+    let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x),
+                                                             marker: PhantomData };
     d.eq(&y)
 }
 
diff --git a/src/test/run-pass/associated-types-issue-20371.rs b/src/test/run-pass/associated-types-issue-20371.rs
index d35b7331d4d..40ef7f3531c 100644
--- a/src/test/run-pass/associated-types-issue-20371.rs
+++ b/src/test/run-pass/associated-types-issue-20371.rs
@@ -11,6 +11,8 @@
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
+use std::marker::MarkerTrait;
+
 impl X for f64 { type Y = int; }
-trait X {type Y; }
+trait X : MarkerTrait { type Y; }
 fn main() {}
diff --git a/src/test/run-pass/associated-types-issue-21212.rs b/src/test/run-pass/associated-types-issue-21212.rs
index ced44250e4d..3c91577362a 100644
--- a/src/test/run-pass/associated-types-issue-21212.rs
+++ b/src/test/run-pass/associated-types-issue-21212.rs
@@ -20,7 +20,8 @@ pub trait Parser {
         panic!()
     }
 }
-impl <P> Parser for P  {
+
+impl <P> Parser for P {
     type Input = ();
 }
 
diff --git a/src/test/run-pass/associated-types-nested-projections.rs b/src/test/run-pass/associated-types-nested-projections.rs
index e3227613159..2ee8ef0d3dd 100644
--- a/src/test/run-pass/associated-types-nested-projections.rs
+++ b/src/test/run-pass/associated-types-nested-projections.rs
@@ -10,11 +10,12 @@
 
 // Test that we can resolve nested projection types. Issue #20666.
 
+use std::marker::MarkerTrait;
 use std::slice;
 
-trait Bound {}
+trait Bound : MarkerTrait {}
 
-impl<'a> Bound for &'a int {}
+impl<'a> Bound for &'a i32 {}
 
 trait IntoIterator {
     type Iter: Iterator;
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
index dd5814f875b..de96af83f59 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds-binding.rs
@@ -13,7 +13,9 @@
 
 #![allow(dead_code)]
 
-pub trait Integral {
+use std::marker::MarkerTrait;
+
+pub trait Integral : MarkerTrait {
     type Opposite;
 }
 
@@ -27,6 +29,8 @@ impl Integral for u32 {
 
 pub trait FnLike<A> {
     type R;
+
+    fn dummy(&self, a: A) -> Self::R { loop { } }
 }
 
 fn foo<T>()
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
index 1d264655bc4..8617750ca53 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
@@ -11,15 +11,17 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-struct Splits<'a, T, P>;
-struct SplitsN<I>;
+use std::marker::PhantomData;
+
+struct Splits<'a, T:'a, P>(PhantomData<(&'a T, P)>);
+struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
-    fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+    fn splitn2<'a, P>(&'a self, n: u32, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
         where P: FnMut(&Self::Item) -> bool;
 }
 
@@ -30,7 +32,7 @@ impl<T> SliceExt2 for [T] {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: u32, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
         SliceExt2::split2(self, pred);
         loop {}
     }
diff --git a/src/test/run-pass/associated-types-normalize-in-bounds.rs b/src/test/run-pass/associated-types-normalize-in-bounds.rs
index 742bab0578e..94cfcb83653 100644
--- a/src/test/run-pass/associated-types-normalize-in-bounds.rs
+++ b/src/test/run-pass/associated-types-normalize-in-bounds.rs
@@ -11,15 +11,17 @@
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-struct Splits<'a, T, P>;
-struct SplitsN<I>;
+use std::marker::PhantomData;
+
+struct Splits<'a, T, P>(PhantomData<(&'a(),T,P)>);
+struct SplitsN<I>(PhantomData<I>);
 
 trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
-    fn splitn2<'a, P>(&'a self, n: uint, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+    fn splitn2<'a, P>(&'a self, n: usize, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
         where P: FnMut(&Self::Item) -> bool;
 }
 
@@ -30,7 +32,7 @@ impl<T> SliceExt2 for [T] {
         loop {}
     }
 
-    fn splitn2<P>(&self, n: uint, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+    fn splitn2<P>(&self, n: usize, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
         self.split2(pred);
         loop {}
     }
diff --git a/src/test/run-pass/associated-types-normalize-unifield-struct.rs b/src/test/run-pass/associated-types-normalize-unifield-struct.rs
index 5aafe93067c..2288e19aae0 100644
--- a/src/test/run-pass/associated-types-normalize-unifield-struct.rs
+++ b/src/test/run-pass/associated-types-normalize-unifield-struct.rs
@@ -13,7 +13,10 @@
 
 
 pub trait OffsetState: Sized {}
-pub trait Offset { type State: OffsetState; }
+pub trait Offset {
+    type State: OffsetState;
+    fn dummy(&self) { }
+}
 
 #[derive(Copy)] pub struct X;
 impl Offset for X { type State = Y; }
diff --git a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
index 0a1a8589dec..c65d2db9b0c 100644
--- a/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
+++ b/src/test/run-pass/associated-types-projection-from-known-type-in-impl.rs
@@ -13,6 +13,8 @@
 trait Int
 {
     type T;
+
+    fn dummy(&self) { }
 }
 
 trait NonZero
diff --git a/src/test/run-pass/associated-types-projection-in-object-type.rs b/src/test/run-pass/associated-types-projection-in-object-type.rs
index 44dd49b7297..a9c34a605ce 100644
--- a/src/test/run-pass/associated-types-projection-in-object-type.rs
+++ b/src/test/run-pass/associated-types-projection-in-object-type.rs
@@ -18,6 +18,8 @@ use std::cell::RefCell;
 
 pub trait Subscriber {
     type Input;
+
+    fn dummy(&self) { }
 }
 
 pub trait Publisher<'a> {
diff --git a/src/test/run-pass/associated-types-projection-in-supertrait.rs b/src/test/run-pass/associated-types-projection-in-supertrait.rs
index e6fec675b03..4d2358fae27 100644
--- a/src/test/run-pass/associated-types-projection-in-supertrait.rs
+++ b/src/test/run-pass/associated-types-projection-in-supertrait.rs
@@ -14,6 +14,8 @@
 trait A
 {
     type TA;
+
+    fn dummy(&self) { }
 }
 
 trait B<TB>
diff --git a/src/test/run-pass/associated-types-projection-in-where-clause.rs b/src/test/run-pass/associated-types-projection-in-where-clause.rs
index 10a459f3c36..3f3f4fbd1d6 100644
--- a/src/test/run-pass/associated-types-projection-in-where-clause.rs
+++ b/src/test/run-pass/associated-types-projection-in-where-clause.rs
@@ -13,6 +13,8 @@
 trait Int
 {
     type T;
+
+    fn dummy(&self) { }
 }
 
 trait NonZero
diff --git a/src/test/run-pass/associated-types-ref-in-struct-literal.rs b/src/test/run-pass/associated-types-ref-in-struct-literal.rs
index 022c8f4cd01..67fe11d8fed 100644
--- a/src/test/run-pass/associated-types-ref-in-struct-literal.rs
+++ b/src/test/run-pass/associated-types-ref-in-struct-literal.rs
@@ -12,6 +12,8 @@
 
 pub trait Foo {
     type Bar;
+
+    fn dummy(&self) { }
 }
 
 impl Foo for int {
diff --git a/src/test/run-pass/associated-types-resolve-lifetime.rs b/src/test/run-pass/associated-types-resolve-lifetime.rs
index e7a8061a346..a4b0b1a6e03 100644
--- a/src/test/run-pass/associated-types-resolve-lifetime.rs
+++ b/src/test/run-pass/associated-types-resolve-lifetime.rs
@@ -15,6 +15,8 @@ trait Get<T> {
 trait Trait<'a> {
     type T: 'static;
     type U: Get<&'a int>;
+
+    fn dummy(&'a self) { }
 }
 
 fn main() {}
diff --git a/src/test/run-pass/associated-types-struct-field-named.rs b/src/test/run-pass/associated-types-struct-field-named.rs
index 1ded34ff3ff..8667f6c8430 100644
--- a/src/test/run-pass/associated-types-struct-field-named.rs
+++ b/src/test/run-pass/associated-types-struct-field-named.rs
@@ -13,6 +13,8 @@
 
 pub trait UnifyKey {
     type Value;
+
+    fn dummy(&self) { }
 }
 
 pub struct Node<K:UnifyKey> {
diff --git a/src/test/run-pass/associated-types-struct-field-numbered.rs b/src/test/run-pass/associated-types-struct-field-numbered.rs
index 3669dec4fbd..9503f78a71b 100644
--- a/src/test/run-pass/associated-types-struct-field-numbered.rs
+++ b/src/test/run-pass/associated-types-struct-field-numbered.rs
@@ -13,6 +13,8 @@
 
 pub trait UnifyKey {
     type Value;
+
+    fn dummy(&self) { }
 }
 
 pub struct Node<K:UnifyKey>(K, K::Value);
diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs
index 3b70e941ac5..c068065ac6a 100644
--- a/src/test/run-pass/associated-types-sugar-path.rs
+++ b/src/test/run-pass/associated-types-sugar-path.rs
@@ -31,8 +31,9 @@ pub fn bar<T: Foo>(a: T, x: T::A) -> T::A {
 // Using a type via an impl.
 trait C {
     fn f();
+    fn g(&self) { }
 }
-struct B<X>;
+struct B<X>(X);
 impl<T: Foo> C for B<T> {
     fn f() {
         let x: T::A = panic!();
diff --git a/src/test/run-pass/borrowck-trait-lifetime.rs b/src/test/run-pass/borrowck-trait-lifetime.rs
index b39f03a93c9..be0c88f557c 100644
--- a/src/test/run-pass/borrowck-trait-lifetime.rs
+++ b/src/test/run-pass/borrowck-trait-lifetime.rs
@@ -12,8 +12,11 @@
 // to the same lifetime on a trait succeeds. See issue #10766.
 
 #![allow(dead_code)]
+
+use std::marker;
+
 fn main() {
-    trait T {}
+    trait T : marker::MarkerTrait {}
 
     fn f<'a, V: T>(v: &'a V) -> &'a T {
         v as &'a T
diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs
index ea711d78dd2..143ebfdabfa 100644
--- a/src/test/run-pass/bug-7295.rs
+++ b/src/test/run-pass/bug-7295.rs
@@ -9,10 +9,10 @@
 // except according to those terms.
 
 pub trait Foo<T> {
-    fn func1<U>(&self, t: U);
+    fn func1<U>(&self, t: U, w: T);
 
-    fn func2<U>(&self, t: U) {
-        self.func1(t);
+    fn func2<U>(&self, t: U, w: T) {
+        self.func1(t, w);
     }
 }
 
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
index c115415bb9b..7eaed910124 100644
--- a/src/test/run-pass/builtin-superkinds-in-metadata.rs
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -16,6 +16,7 @@
 extern crate trait_superkinds_in_metadata;
 use trait_superkinds_in_metadata::{RequiresRequiresShareAndSend, RequiresShare};
 use trait_superkinds_in_metadata::{RequiresCopy};
+use std::marker;
 
 #[derive(Copy)]
 struct X<T>(T);
diff --git a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
index 7e1b2821937..964c28dc945 100644
--- a/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
+++ b/src/test/run-pass/builtin-superkinds-phantom-typaram.rs
@@ -12,10 +12,12 @@
 // super-builtin-kind of a trait, if the type parameter is never used,
 // the type can implement the trait anyway.
 
+use std::marker;
+
 trait Foo : Send { }
 
-struct X<T>(());
+struct X<T> { marker: marker::PhantomData<T> }
 
-impl <T> Foo for X<T> { }
+impl<T:Send> Foo for X<T> { }
 
 pub fn main() { }
diff --git a/src/test/run-pass/class-typarams.rs b/src/test/run-pass/class-typarams.rs
index 68457095944..b56a749d33b 100644
--- a/src/test/run-pass/class-typarams.rs
+++ b/src/test/run-pass/class-typarams.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::PhantomData;
+
 struct cat<U> {
     meows : uint,
-
     how_hungry : int,
+    m: PhantomData<U>
 }
 
 impl<U> cat<U> {
@@ -22,7 +24,8 @@ impl<U> cat<U> {
 fn cat<U>(in_x : uint, in_y : int) -> cat<U> {
     cat {
         meows: in_x,
-        how_hungry: in_y
+        how_hungry: in_y,
+        m: PhantomData
     }
 }
 
diff --git a/src/test/run-pass/dst-coercions.rs b/src/test/run-pass/dst-coercions.rs
index dbad546ce1a..30ed0b8e402 100644
--- a/src/test/run-pass/dst-coercions.rs
+++ b/src/test/run-pass/dst-coercions.rs
@@ -11,7 +11,7 @@
 // Test coercions involving DST and/or raw pointers
 
 struct S;
-trait T {}
+trait T { fn dummy(&self) { } }
 impl T for S {}
 
 pub fn main() {
diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs
index 797c26556aa..023376ce473 100644
--- a/src/test/run-pass/enum-null-pointer-opt.rs
+++ b/src/test/run-pass/enum-null-pointer-opt.rs
@@ -16,7 +16,7 @@ use std::mem::size_of;
 use std::rc::Rc;
 use std::sync::Arc;
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 
 fn main() {
     // Functions
diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs
index 066a5f9580a..382c5c58e92 100644
--- a/src/test/run-pass/explicit-self-generic.rs
+++ b/src/test/run-pass/explicit-self-generic.rs
@@ -15,21 +15,19 @@
 struct LM { resize_at: uint, size: uint }
 
 enum HashMap<K,V> {
-    HashMap_(LM)
+    HashMap_(LM, Vec<(K,V)>)
 }
 
-impl<K,V> Copy for HashMap<K,V> {}
-
 fn linear_map<K,V>() -> HashMap<K,V> {
     HashMap::HashMap_(LM{
         resize_at: 32,
-        size: 0})
+        size: 0}, Vec::new())
 }
 
 impl<K,V> HashMap<K,V> {
     pub fn len(&mut self) -> uint {
         match *self {
-            HashMap::HashMap_(l) => l.size
+            HashMap::HashMap_(ref l, _) => l.size
         }
     }
 }
diff --git a/src/test/run-pass/generic-default-type-params-cross-crate.rs b/src/test/run-pass/generic-default-type-params-cross-crate.rs
index ed8c6e73255..bf02b82d1a0 100644
--- a/src/test/run-pass/generic-default-type-params-cross-crate.rs
+++ b/src/test/run-pass/generic-default-type-params-cross-crate.rs
@@ -12,13 +12,13 @@
 
 extern crate default_type_params_xc;
 
-struct Vec<T, A = default_type_params_xc::Heap>;
+struct Vec<T, A = default_type_params_xc::Heap>(Option<(T,A)>);
 
 struct Foo;
 
 fn main() {
-    let _a = Vec::<int>;
-    let _b = Vec::<int, default_type_params_xc::FakeHeap>;
-    let _c = default_type_params_xc::FakeVec::<int>;
-    let _d = default_type_params_xc::FakeVec::<int, Foo>;
+    let _a = Vec::<int>(None);
+    let _b = Vec::<int, default_type_params_xc::FakeHeap>(None);
+    let _c = default_type_params_xc::FakeVec::<int> { f: None };
+    let _d = default_type_params_xc::FakeVec::<int, Foo> { f: None };
 }
diff --git a/src/test/run-pass/hrtb-opt-in-copy.rs b/src/test/run-pass/hrtb-opt-in-copy.rs
index 9c9f95f61e9..7b16bb867e7 100644
--- a/src/test/run-pass/hrtb-opt-in-copy.rs
+++ b/src/test/run-pass/hrtb-opt-in-copy.rs
@@ -18,7 +18,7 @@
 
 #![allow(dead_code)]
 
-use std::marker;
+use std::marker::PhantomData;
 
 #[derive(Copy)]
 struct Foo<T> { x: T }
@@ -26,7 +26,7 @@ struct Foo<T> { x: T }
 type Ty<'tcx> = &'tcx TyS<'tcx>;
 
 enum TyS<'tcx> {
-    Boop(marker::InvariantLifetime<'tcx>)
+    Boop(PhantomData<*mut &'tcx ()>)
 }
 
 #[derive(Copy)]
diff --git a/src/test/run-pass/inner-static.rs b/src/test/run-pass/inner-static.rs
index f9b430c1553..e4026a8fd01 100644
--- a/src/test/run-pass/inner-static.rs
+++ b/src/test/run-pass/inner-static.rs
@@ -13,9 +13,9 @@
 extern crate inner_static;
 
 pub fn main() {
-    let a = inner_static::A::<()>;
-    let b = inner_static::B::<()>;
-    let c = inner_static::test::A::<()>;
+    let a = inner_static::A::<()> { v: () };
+    let b = inner_static::B::<()> { v: () };
+    let c = inner_static::test::A::<()> { v: () };
     assert_eq!(a.bar(), 2);
     assert_eq!(b.bar(), 4);
     assert_eq!(c.bar(), 6);
diff --git a/src/test/run-pass/issue-10456.rs b/src/test/run-pass/issue-10456.rs
index b714d87f4ef..da73c4b27ac 100644
--- a/src/test/run-pass/issue-10456.rs
+++ b/src/test/run-pass/issue-10456.rs
@@ -14,7 +14,9 @@ pub trait Bar {
     fn bar(&self);
 }
 
-pub trait Baz {}
+pub trait Baz {
+    fn baz(&self) { }
+}
 
 impl<T: Baz> Bar for T {
     fn bar(&self) {}
diff --git a/src/test/run-pass/issue-10802.rs b/src/test/run-pass/issue-10802.rs
index de2b4c51e52..174a69e1135 100644
--- a/src/test/run-pass/issue-10802.rs
+++ b/src/test/run-pass/issue-10802.rs
@@ -29,7 +29,7 @@ impl Drop for DroppableEnum {
     }
 }
 
-trait MyTrait { }
+trait MyTrait { fn dummy(&self) { } }
 impl MyTrait for Box<DroppableStruct> {}
 impl MyTrait for Box<DroppableEnum> {}
 
diff --git a/src/test/run-pass/issue-10902.rs b/src/test/run-pass/issue-10902.rs
index 324a1701b2f..7fab6662ee0 100644
--- a/src/test/run-pass/issue-10902.rs
+++ b/src/test/run-pass/issue-10902.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub mod two_tuple {
-    pub trait T {}
+    pub trait T { fn dummy(&self) { } }
     pub struct P<'a>(&'a (T + 'a), &'a (T + 'a));
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P(car, cdr)
@@ -17,7 +17,7 @@ pub mod two_tuple {
 }
 
 pub mod two_fields {
-    pub trait T {}
+    pub trait T { fn dummy(&self) { } }
     pub struct P<'a> { car: &'a (T + 'a), cdr: &'a (T + 'a) }
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P{ car: car, cdr: cdr }
diff --git a/src/test/run-pass/issue-11205.rs b/src/test/run-pass/issue-11205.rs
index d7c6c1b1bb2..1325b51a54f 100644
--- a/src/test/run-pass/issue-11205.rs
+++ b/src/test/run-pass/issue-11205.rs
@@ -12,7 +12,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 impl Foo for int {}
 fn foo(_: [&Foo; 2]) {}
 fn foos(_: &[&Foo]) {}
diff --git a/src/test/run-pass/issue-11384.rs b/src/test/run-pass/issue-11384.rs
index a511149b05e..26634fabf5a 100644
--- a/src/test/run-pass/issue-11384.rs
+++ b/src/test/run-pass/issue-11384.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Common {}
+trait Common { fn dummy(&self) { } }
 
 impl<'t, T> Common for (T, &'t T) {}
 
diff --git a/src/test/run-pass/issue-11612.rs b/src/test/run-pass/issue-11612.rs
index fa25d25df05..3c69377b375 100644
--- a/src/test/run-pass/issue-11612.rs
+++ b/src/test/run-pass/issue-11612.rs
@@ -12,7 +12,7 @@
 // We weren't updating the auto adjustments with all the resolved
 // type information after type check.
 
-trait A {}
+trait A { fn dummy(&self) { } }
 
 struct B<'a, T:'a> {
     f: &'a T
diff --git a/src/test/run-pass/issue-11677.rs b/src/test/run-pass/issue-11677.rs
index 6fa45058694..7cccac4483d 100644
--- a/src/test/run-pass/issue-11677.rs
+++ b/src/test/run-pass/issue-11677.rs
@@ -14,13 +14,18 @@
 
 // this code used to cause an ICE
 
-trait X<T> {}
+use std::marker;
+
+trait X<T> {
+    fn dummy(&self) -> T { panic!() }
+}
 
 struct S<T> {f: Box<X<T>+'static>,
              g: Box<X<T>+'static>}
 
 struct F;
-impl X<int> for F {}
+impl X<int> for F {
+}
 
 fn main() {
   S {f: box F, g: box F};
diff --git a/src/test/run-pass/issue-13105.rs b/src/test/run-pass/issue-13105.rs
index 7fab36bd64e..64807dc44e0 100644
--- a/src/test/run-pass/issue-13105.rs
+++ b/src/test/run-pass/issue-13105.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo {
+use std::marker::MarkerTrait;
+
+trait Foo : MarkerTrait {
     fn quux(u8) {}
 }
 
diff --git a/src/test/run-pass/issue-14399.rs b/src/test/run-pass/issue-14399.rs
index 7e533c2cf86..4f3db1352bb 100644
--- a/src/test/run-pass/issue-14399.rs
+++ b/src/test/run-pass/issue-14399.rs
@@ -19,7 +19,7 @@
 #[derive(Clone)]
 struct B1;
 
-trait A {}
+trait A : std::marker::MarkerTrait {}
 impl A for B1 {}
 
 fn main() {
diff --git a/src/test/run-pass/issue-14589.rs b/src/test/run-pass/issue-14589.rs
index d9763baa826..71d88ee6215 100644
--- a/src/test/run-pass/issue-14589.rs
+++ b/src/test/run-pass/issue-14589.rs
@@ -17,17 +17,18 @@
 fn main() {
     send::<Box<Foo>>(box Output(0));
     Test::<Box<Foo>>::foo(box Output(0));
-    Test::<Box<Foo>>.send(box Output(0));
+    Test::<Box<Foo>>::new().send(box Output(0));
 }
 
 fn send<T>(_: T) {}
 
-struct Test<T>;
+struct Test<T> { marker: std::marker::PhantomData<T> }
 impl<T> Test<T> {
+    fn new() -> Test<T> { Test { marker: ::std::marker::PhantomData } }
     fn foo(_: T) {}
     fn send(&self, _: T) {}
 }
 
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
 struct Output(int);
 impl Foo for Output {}
diff --git a/src/test/run-pass/issue-14958.rs b/src/test/run-pass/issue-14958.rs
index 814a743648d..6335f79be6c 100644
--- a/src/test/run-pass/issue-14958.rs
+++ b/src/test/run-pass/issue-14958.rs
@@ -10,7 +10,7 @@
 
 #![feature(unboxed_closures)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { }}
 
 struct Bar;
 
diff --git a/src/test/run-pass/issue-14959.rs b/src/test/run-pass/issue-14959.rs
index 33281d7d78f..53d0f7dae05 100644
--- a/src/test/run-pass/issue-14959.rs
+++ b/src/test/run-pass/issue-14959.rs
@@ -12,8 +12,8 @@
 
 use std::ops::Fn;
 
-trait Response {}
-trait Request {}
+trait Response { fn dummy(&self) { } }
+trait Request { fn dummy(&self) { } }
 trait Ingot<R, S> {
     fn enter(&mut self, _: &mut R, _: &mut S, a: &mut Alloy) -> Status;
 }
@@ -21,7 +21,7 @@ trait Ingot<R, S> {
 #[allow(dead_code)]
 struct HelloWorld;
 
-struct SendFile<'a>;
+struct SendFile;
 struct Alloy;
 enum Status {
     Continue
@@ -33,7 +33,7 @@ impl Alloy {
     }
 }
 
-impl<'a, 'b> Fn<(&'b mut (Response+'b),)> for SendFile<'a> {
+impl<'b> Fn<(&'b mut (Response+'b),)> for SendFile {
     type Output = ();
 
     extern "rust-call" fn call(&self, (_res,): (&'b mut (Response+'b),)) {}
diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs
index c75c6725461..6a4f78442d1 100644
--- a/src/test/run-pass/issue-15858.rs
+++ b/src/test/run-pass/issue-15858.rs
@@ -12,21 +12,21 @@
 
 static mut DROP_RAN: bool = false;
 
-trait Bar<'b> {
+trait Bar {
     fn do_something(&mut self);
 }
 
-struct BarImpl<'b>;
+struct BarImpl;
 
-impl<'b> Bar<'b> for BarImpl<'b> {
+impl Bar for BarImpl {
     fn do_something(&mut self) {}
 }
 
 
-struct Foo<B>;
+struct Foo<B>(B);
 
 #[unsafe_destructor]
-impl<'b, B: Bar<'b>> Drop for Foo<B> {
+impl<B: Bar> Drop for Foo<B> {
     fn drop(&mut self) {
         unsafe {
             DROP_RAN = true;
@@ -37,7 +37,7 @@ impl<'b, B: Bar<'b>> Drop for Foo<B> {
 
 fn main() {
     {
-       let _x: Foo<BarImpl> = Foo;
+       let _x: Foo<BarImpl> = Foo(BarImpl);
     }
     unsafe {
         assert_eq!(DROP_RAN, true);
diff --git a/src/test/run-pass/issue-16596.rs b/src/test/run-pass/issue-16596.rs
index e01de3a3262..1ba7b142e5e 100644
--- a/src/test/run-pass/issue-16596.rs
+++ b/src/test/run-pass/issue-16596.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait MatrixRow {}
+trait MatrixRow { fn dummy(&self) { }}
 
 struct Mat;
 
diff --git a/src/test/run-pass/issue-16643.rs b/src/test/run-pass/issue-16643.rs
index b118c9573cd..4e57c55c5f7 100644
--- a/src/test/run-pass/issue-16643.rs
+++ b/src/test/run-pass/issue-16643.rs
@@ -13,5 +13,5 @@
 extern crate "issue-16643" as i;
 
 pub fn main() {
-    i::TreeBuilder::<uint>.process_token();
+    i::TreeBuilder { h: 3u }.process_token();
 }
diff --git a/src/test/run-pass/issue-17662.rs b/src/test/run-pass/issue-17662.rs
index 45e70f59f33..7bd41cc5b52 100644
--- a/src/test/run-pass/issue-17662.rs
+++ b/src/test/run-pass/issue-17662.rs
@@ -12,12 +12,14 @@
 
 extern crate "issue-17662" as i;
 
-struct Bar<'a>;
+use std::marker;
+
+struct Bar<'a> { m: marker::PhantomData<&'a ()> }
 
 impl<'a> i::Foo<'a, uint> for Bar<'a> {
     fn foo(&self) -> uint { 5_usize }
 }
 
 pub fn main() {
-    assert_eq!(i::foo(&Bar), 5);
+    assert_eq!(i::foo(&Bar { m: marker::PhantomData }), 5);
 }
diff --git a/src/test/run-pass/issue-17732.rs b/src/test/run-pass/issue-17732.rs
index b4bd55da597..de9611f2592 100644
--- a/src/test/run-pass/issue-17732.rs
+++ b/src/test/run-pass/issue-17732.rs
@@ -10,8 +10,9 @@
 
 trait Person {
     type string;
+    fn dummy(&self) { }
 }
 
-struct Someone<P: Person>;
+struct Someone<P: Person>(std::marker::PhantomData<P>);
 
 fn main() {}
diff --git a/src/test/run-pass/issue-17771.rs b/src/test/run-pass/issue-17771.rs
index 1e9550acef4..2f1b0342b8e 100644
--- a/src/test/run-pass/issue-17771.rs
+++ b/src/test/run-pass/issue-17771.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Aaa {}
+trait Aaa { fn dummy(&self) { } }
 
 impl<'a> Aaa for &'a mut (Aaa + 'a) {}
 
diff --git a/src/test/run-pass/issue-17816.rs b/src/test/run-pass/issue-17816.rs
index f8fbd680dcb..a976eccf89e 100644
--- a/src/test/run-pass/issue-17816.rs
+++ b/src/test/run-pass/issue-17816.rs
@@ -10,9 +10,11 @@
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
+
 fn main() {
-    struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F }
+    struct Symbol<'a, F: Fn(Vec<&'a str>) -> &'a str> { function: F, marker: PhantomData<&'a ()> }
     let f = |x: Vec<&str>| -> &str "foobar";
-    let sym = Symbol { function: f };
+    let sym = Symbol { function: f, marker: PhantomData };
     (sym.function)(vec![]);
 }
diff --git a/src/test/run-pass/issue-17904.rs b/src/test/run-pass/issue-17904.rs
index 3ce347d67e3..58a0872a571 100644
--- a/src/test/run-pass/issue-17904.rs
+++ b/src/test/run-pass/issue-17904.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Foo<T> where T: Copy;
+// Test that we can parse where clauses on various forms of tuple
+// structs.
+
 struct Bar<T>(T) where T: Copy;
 struct Bleh<T, U>(T, U) where T: Copy, U: Sized;
 struct Baz<T> where T: Copy {
diff --git a/src/test/run-pass/issue-18232.rs b/src/test/run-pass/issue-18232.rs
index 15cf5870d40..67b3239d351 100644
--- a/src/test/run-pass/issue-18232.rs
+++ b/src/test/run-pass/issue-18232.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Cursor<'a>;
+struct Cursor<'a>(::std::marker::PhantomData<&'a ()>);
 
 trait CursorNavigator {
     fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool;
@@ -23,7 +23,7 @@ impl CursorNavigator for SimpleNavigator {
 }
 
 fn main() {
-    let mut c = Cursor;
+    let mut c = Cursor(::std::marker::PhantomData);
     let n = SimpleNavigator;
     n.init_cursor(&mut c);
 }
diff --git a/src/test/run-pass/issue-18906.rs b/src/test/run-pass/issue-18906.rs
index 11ffb4198da..16dd84315ed 100644
--- a/src/test/run-pass/issue-18906.rs
+++ b/src/test/run-pass/issue-18906.rs
@@ -24,7 +24,7 @@ fn bar<K, Q>(k: &K, q: &Q) where K: Borrow<Q>, Q: Foo {
     q.foo(k.borrow())
 }
 
-struct MyTree<K>;
+struct MyTree<K>(K);
 
 impl<K> MyTree<K> {
     // This caused a failure in #18906
diff --git a/src/test/run-pass/issue-19121.rs b/src/test/run-pass/issue-19121.rs
index d95f74ef2a2..222f67af437 100644
--- a/src/test/run-pass/issue-19121.rs
+++ b/src/test/run-pass/issue-19121.rs
@@ -13,6 +13,8 @@
 
 trait Foo {
     type A;
+
+    fn dummy(&self) { }
 }
 
 fn bar(x: &Foo) {}
diff --git a/src/test/run-pass/issue-19129-2.rs b/src/test/run-pass/issue-19129-2.rs
index d6b3a1908b8..cf0f48e025a 100644
--- a/src/test/run-pass/issue-19129-2.rs
+++ b/src/test/run-pass/issue-19129-2.rs
@@ -11,7 +11,7 @@
 trait Trait<Input> {
     type Output;
 
-    fn method() -> bool { false }
+    fn method(&self, i: Input) -> bool { false }
 }
 
 fn main() {}
diff --git a/src/test/run-pass/issue-19135.rs b/src/test/run-pass/issue-19135.rs
index 031a63ba474..5e6dd567d63 100644
--- a/src/test/run-pass/issue-19135.rs
+++ b/src/test/run-pass/issue-19135.rs
@@ -10,13 +10,15 @@
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
+
 #[derive(Debug)]
-struct LifetimeStruct<'a>;
+struct LifetimeStruct<'a>(PhantomData<&'a ()>);
 
 fn main() {
     takes_hrtb_closure(|lts| println!("{:?}", lts));
 }
 
 fn takes_hrtb_closure<F: for<'a>FnMut(LifetimeStruct<'a>)>(mut f: F) {
-    f(LifetimeStruct);
+    f(LifetimeStruct(PhantomData));
 }
diff --git a/src/test/run-pass/issue-19358.rs b/src/test/run-pass/issue-19358.rs
index ff657376ecc..8b5269ab92f 100644
--- a/src/test/run-pass/issue-19358.rs
+++ b/src/test/run-pass/issue-19358.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {}
+trait Trait { fn dummy(&self) { } }
 
 #[derive(Debug)]
 struct Foo<T: Trait> {
diff --git a/src/test/run-pass/issue-19398.rs b/src/test/run-pass/issue-19398.rs
index 1196162568a..e603167b26b 100644
--- a/src/test/run-pass/issue-19398.rs
+++ b/src/test/run-pass/issue-19398.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 trait T {
-    unsafe extern "Rust" fn foo();
+    unsafe extern "Rust" fn foo(&self);
 }
 
 impl T for () {
-    unsafe extern "Rust" fn foo() {}
+    unsafe extern "Rust" fn foo(&self) {}
 }
 
 fn main() {}
diff --git a/src/test/run-pass/issue-19479.rs b/src/test/run-pass/issue-19479.rs
index 91bc645b2d4..38a7af3a695 100644
--- a/src/test/run-pass/issue-19479.rs
+++ b/src/test/run-pass/issue-19479.rs
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Base {}
+trait Base {
+    fn dummy(&self) { }
+}
 trait AssocA {
     type X: Base;
+    fn dummy(&self) { }
 }
 trait AssocB {
     type Y: Base;
+    fn dummy(&self) { }
 }
 impl<T: AssocA> AssocB for T {
     type Y = <T as AssocA>::X;
diff --git a/src/test/run-pass/issue-19631.rs b/src/test/run-pass/issue-19631.rs
index 43116f63641..7bb0d055b84 100644
--- a/src/test/run-pass/issue-19631.rs
+++ b/src/test/run-pass/issue-19631.rs
@@ -10,6 +10,7 @@
 
 trait PoolManager {
     type C;
+    fn dummy(&self) { }
 }
 
 struct InnerPool<M> {
diff --git a/src/test/run-pass/issue-19632.rs b/src/test/run-pass/issue-19632.rs
index 01a073a6889..4339339d74c 100644
--- a/src/test/run-pass/issue-19632.rs
+++ b/src/test/run-pass/issue-19632.rs
@@ -10,6 +10,7 @@
 
 trait PoolManager {
     type C;
+    fn dummy(&self) { }
 }
 
 struct InnerPool<M: PoolManager> {
diff --git a/src/test/run-pass/issue-20055-box-trait.rs b/src/test/run-pass/issue-20055-box-trait.rs
index 836e78b5b51..572a0d82528 100644
--- a/src/test/run-pass/issue-20055-box-trait.rs
+++ b/src/test/run-pass/issue-20055-box-trait.rs
@@ -16,7 +16,9 @@
 // whichever arm is run, and subsequently dropped at the end of the
 // statement surrounding the `match`.
 
-trait Boo { }
+trait Boo {
+    fn dummy(&self) { }
+}
 
 impl Boo for [i8; 1] { }
 impl Boo for [i8; 2] { }
diff --git a/src/test/run-pass/issue-20343.rs b/src/test/run-pass/issue-20343.rs
index 79034a4a4a6..2f9e8feed24 100644
--- a/src/test/run-pass/issue-20343.rs
+++ b/src/test/run-pass/issue-20343.rs
@@ -16,7 +16,7 @@ struct B { b: u32 }
 struct C;
 struct D;
 
-trait T<A> {}
+trait T<A> { fn dummy(&self, a: A) { } }
 impl<A> T<A> for () {}
 
 impl B {
diff --git a/src/test/run-pass/issue-20763-1.rs b/src/test/run-pass/issue-20763-1.rs
index 911ee715da2..97c06ac9826 100644
--- a/src/test/run-pass/issue-20763-1.rs
+++ b/src/test/run-pass/issue-20763-1.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait T0 { type O; }
+trait T0 {
+    type O;
+    fn dummy(&self) { }
+}
 
 struct S<A>(A);
 impl<A> T0 for S<A> { type O = A; }
diff --git a/src/test/run-pass/issue-20763-2.rs b/src/test/run-pass/issue-20763-2.rs
index a17c7b6ade4..d9701763571 100644
--- a/src/test/run-pass/issue-20763-2.rs
+++ b/src/test/run-pass/issue-20763-2.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait T0 { type O; }
+trait T0 {
+    type O;
+    fn dummy(&self) { }
+}
 
 struct S<A>(A);
 impl<A> T0 for S<A> { type O = A; }
diff --git a/src/test/run-pass/issue-21363.rs b/src/test/run-pass/issue-21363.rs
index 2fc1d9fd643..71bb3d39fe1 100644
--- a/src/test/run-pass/issue-21363.rs
+++ b/src/test/run-pass/issue-21363.rs
@@ -12,6 +12,7 @@
 
 trait Iterator {
     type Item;
+    fn dummy(&self) { }
 }
 
 impl<'a, T> Iterator for &'a mut (Iterator<Item=T> + 'a) {
diff --git a/src/test/run-pass/issue-21909.rs b/src/test/run-pass/issue-21909.rs
index 5bbc90b2606..55b61dd1945 100644
--- a/src/test/run-pass/issue-21909.rs
+++ b/src/test/run-pass/issue-21909.rs
@@ -8,11 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A<X> {}
+trait A<X> {
+    fn dummy(&self, arg: X);
+}
 
 trait B {
     type X;
     type Y: A<Self::X>;
+
+    fn dummy(&self);
 }
 
 fn main () { }
diff --git a/src/test/run-pass/issue-2311-2.rs b/src/test/run-pass/issue-2311-2.rs
index e0b98ab1965..5529d51b408 100644
--- a/src/test/run-pass/issue-2311-2.rs
+++ b/src/test/run-pass/issue-2311-2.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait clam<A> { }
+trait clam<A> {
+    fn get(self) -> A;
+}
+
 struct foo<A> {
     x: A,
 }
diff --git a/src/test/run-pass/issue-2311.rs b/src/test/run-pass/issue-2311.rs
index dc873ed08d7..b6b3114e2a4 100644
--- a/src/test/run-pass/issue-2311.rs
+++ b/src/test/run-pass/issue-2311.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
 trait foo<A> {
    fn bar<B,C:clam<A>>(&self, c: C) -> B;
 }
diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs
index 8c597552d75..3f273b56efd 100644
--- a/src/test/run-pass/issue-2312.rs
+++ b/src/test/run-pass/issue-2312.rs
@@ -10,7 +10,7 @@
 
 // Testing that the B's are resolved
 
-trait clam<A> { }
+trait clam<A> { fn get(self) -> A; }
 
 struct foo(int);
 
diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs
index 2608c89d155..c005699ce30 100644
--- a/src/test/run-pass/issue-2611-3.rs
+++ b/src/test/run-pass/issue-2611-3.rs
@@ -12,7 +12,7 @@
 // than the traits require.
 
 trait A {
-  fn b<C:Sync,D>(x: C) -> C;
+  fn b<C:Sync,D>(&self, x: C) -> C;
 }
 
 struct E {
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F,G>(_x: F) -> F { panic!() }
+  fn b<F,G>(&self, _x: F) -> F { panic!() }
   //~^ ERROR in method `b`, type parameter 0 has 1 bound, but
 }
 
diff --git a/src/test/run-pass/issue-2734.rs b/src/test/run-pass/issue-2734.rs
index 7ca439a1a19..a7b53db6b05 100644
--- a/src/test/run-pass/issue-2734.rs
+++ b/src/test/run-pass/issue-2734.rs
@@ -11,7 +11,9 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait hax { }
+trait hax {
+    fn dummy(&self) { }
+}
 impl<A> hax for A { }
 
 fn perform_hax<T: 'static>(x: Box<T>) -> Box<hax+'static> {
diff --git a/src/test/run-pass/issue-2735.rs b/src/test/run-pass/issue-2735.rs
index 962359537bf..1594b94879c 100644
--- a/src/test/run-pass/issue-2735.rs
+++ b/src/test/run-pass/issue-2735.rs
@@ -11,7 +11,9 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-trait hax { }
+trait hax {
+    fn dummy(&self) { }
+}
 impl<A> hax for A { }
 
 fn perform_hax<T: 'static>(x: Box<T>) -> Box<hax+'static> {
diff --git a/src/test/run-pass/issue-4107.rs b/src/test/run-pass/issue-4107.rs
index 2ed662e9f2d..d660f300ada 100644
--- a/src/test/run-pass/issue-4107.rs
+++ b/src/test/run-pass/issue-4107.rs
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 pub fn main() {
-    let _id: &Mat2<f64> = &Matrix::identity();
+    let _id: &Mat2<f64> = &Matrix::identity(1.0);
 }
 
-pub trait Index<Index,Result> { }
+pub trait Index<Index,Result> { fn get(&self, Index) -> Result { panic!() } }
 pub trait Dimensional<T>: Index<uint, T> { }
 
-pub struct Mat2<T> { x: () }
-pub struct Vec2<T> { x: () }
+pub struct Mat2<T> { x: T }
+pub struct Vec2<T> { x: T }
 
 impl<T> Dimensional<Vec2<T>> for Mat2<T> { }
 impl<T> Index<uint, Vec2<T>> for Mat2<T> { }
@@ -25,9 +25,9 @@ impl<T> Dimensional<T> for Vec2<T> { }
 impl<T> Index<uint, T> for Vec2<T> { }
 
 pub trait Matrix<T,V>: Dimensional<V> {
-    fn identity() -> Self;
+    fn identity(t:T) -> Self;
 }
 
 impl<T> Matrix<T, Vec2<T>> for Mat2<T> {
-    fn identity() -> Mat2<T> { Mat2{ x: () } }
+    fn identity(t:T) -> Mat2<T> { Mat2{ x: t } }
 }
diff --git a/src/test/run-pass/issue-5192.rs b/src/test/run-pass/issue-5192.rs
index bb79cd4d046..a6f3771bf62 100644
--- a/src/test/run-pass/issue-5192.rs
+++ b/src/test/run-pass/issue-5192.rs
@@ -12,6 +12,7 @@
 #![feature(box_syntax)]
 
 pub trait EventLoop {
+    fn dummy(&self) { }
 }
 
 pub struct UvEventLoop {
diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs
index fd39bcc6b61..59bca87bed0 100644
--- a/src/test/run-pass/issue-5708.rs
+++ b/src/test/run-pass/issue-5708.rs
@@ -48,7 +48,9 @@ pub fn main() {
 
 
 // minimal
-pub trait MyTrait<T> { }
+pub trait MyTrait<T> {
+    fn dummy(&self, t: T) -> T { panic!() }
+}
 
 pub struct MyContainer<'a, T> {
     foos: Vec<&'a (MyTrait<T>+'a)> ,
diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs
index d96862b588f..1746a6281dc 100644
--- a/src/test/run-pass/issue-6128.rs
+++ b/src/test/run-pass/issue-6128.rs
@@ -17,6 +17,7 @@ use std::collections::HashMap;
 
 trait Graph<Node, Edge> {
     fn f(&self, Edge);
+    fn g(&self, Node);
 
 }
 
@@ -24,6 +25,9 @@ impl<E> Graph<int, E> for HashMap<int, int> {
     fn f(&self, _e: E) {
         panic!();
     }
+    fn g(&self, _e: int) {
+        panic!();
+    }
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/issue-6318.rs b/src/test/run-pass/issue-6318.rs
index 1d8fe8bfce8..6e608d34bd5 100644
--- a/src/test/run-pass/issue-6318.rs
+++ b/src/test/run-pass/issue-6318.rs
@@ -15,7 +15,9 @@ pub enum Thing {
     A(Box<Foo+'static>)
 }
 
-pub trait Foo {}
+pub trait Foo {
+    fn dummy(&self) { }
+}
 
 pub struct Struct;
 
diff --git a/src/test/run-pass/issue-7575.rs b/src/test/run-pass/issue-7575.rs
index 225213db6a4..77cfc7f0cf6 100644
--- a/src/test/run-pass/issue-7575.rs
+++ b/src/test/run-pass/issue-7575.rs
@@ -10,6 +10,7 @@
 
 trait Foo {
     fn new() -> bool { false }
+    fn dummy(&self) { }
 }
 
 trait Bar {
diff --git a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
index b6dfbb1ca42..736860947f2 100644
--- a/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/run-pass/issue-7673-cast-generically-implemented-trait.rs
@@ -19,7 +19,10 @@
 
 pub fn main() {}
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
+
 impl<T: 'static> A for T {}
 
 fn owned2<T: 'static>(a: Box<T>) { a as Box<A>; }
diff --git a/src/test/run-pass/issue-7911.rs b/src/test/run-pass/issue-7911.rs
index 86948ebcb91..3eb593708be 100644
--- a/src/test/run-pass/issue-7911.rs
+++ b/src/test/run-pass/issue-7911.rs
@@ -14,7 +14,9 @@
 // with different mutability in macro in two methods
 
 #![allow(unused_variable)] // unused foobar_immut + foobar_mut
-trait FooBar {}
+trait FooBar {
+    fn dummy(&self) { }
+}
 struct Bar(i32);
 struct Foo { bar: Bar }
 
diff --git a/src/test/run-pass/issue-8248.rs b/src/test/run-pass/issue-8248.rs
index 377b9ce262c..7bc8dbe616f 100644
--- a/src/test/run-pass/issue-8248.rs
+++ b/src/test/run-pass/issue-8248.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
diff --git a/src/test/run-pass/issue-8249.rs b/src/test/run-pass/issue-8249.rs
index 44f07def531..83c9e9bf450 100644
--- a/src/test/run-pass/issue-8249.rs
+++ b/src/test/run-pass/issue-8249.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {}
+trait A {
+    fn dummy(&self) { }
+}
 struct B;
 impl A for B {}
 
diff --git a/src/test/run-pass/issue-9719.rs b/src/test/run-pass/issue-9719.rs
index 8fc86eb49e7..aa1e65efaa4 100644
--- a/src/test/run-pass/issue-9719.rs
+++ b/src/test/run-pass/issue-9719.rs
@@ -13,7 +13,9 @@ mod a {
         A(T),
     }
 
-    pub trait X {}
+    pub trait X {
+        fn dummy(&self) { }
+    }
     impl X for int {}
 
     pub struct Z<'a>(Enum<&'a (X+'a)>);
@@ -21,7 +23,9 @@ mod a {
 }
 
 mod b {
-    trait X {}
+    trait X {
+        fn dummy(&self) { }
+    }
     impl X for int {}
     struct Y<'a>{
         x:Option<&'a (X+'a)>,
diff --git a/src/test/run-pass/lint-cstack.rs b/src/test/run-pass/lint-cstack.rs
index 2194453aac2..f180ffcd4e8 100644
--- a/src/test/run-pass/lint-cstack.rs
+++ b/src/test/run-pass/lint-cstack.rs
@@ -15,7 +15,7 @@ extern {
 }
 
 trait A {
-    fn foo() {
+    fn foo(&self) {
         unsafe {
             rust_get_test_int();
         }
diff --git a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
index 25ce0d774eb..cec9753a2fe 100644
--- a/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
+++ b/src/test/run-pass/method-early-bound-lifetimes-on-self.rs
@@ -13,7 +13,11 @@
 
 #![allow(dead_code)]
 
-struct Cursor<'a>;
+use std::marker;
+
+struct Cursor<'a> {
+    m: marker::PhantomData<&'a ()>
+}
 
 trait CursorNavigator {
     fn init_cursor<'a, 'b:'a>(&'a self, cursor: &mut Cursor<'b>) -> bool;
@@ -28,7 +32,7 @@ impl CursorNavigator for SimpleNavigator {
 }
 
 fn main() {
-    let mut c = Cursor;
+    let mut c = Cursor { m: marker::PhantomData };
     let n = SimpleNavigator;
     n.init_cursor(&mut c);
 }
diff --git a/src/test/run-pass/method-recursive-blanket-impl.rs b/src/test/run-pass/method-recursive-blanket-impl.rs
index 338bd89ab5c..15eb2ae2e4b 100644
--- a/src/test/run-pass/method-recursive-blanket-impl.rs
+++ b/src/test/run-pass/method-recursive-blanket-impl.rs
@@ -17,16 +17,16 @@ use std::marker::Sized;
 
 // Note: this must be generic for the problem to show up
 trait Foo<A> {
-    fn foo(&self);
+    fn foo(&self, a: A);
 }
 
 impl Foo<u8> for [u8] {
-    fn foo(&self) {}
+    fn foo(&self, a: u8) {}
 }
 
 impl<'a, A, T> Foo<A> for &'a T where T: Foo<A> {
-    fn foo(&self) {
-        Foo::foo(*self)
+    fn foo(&self, a: A) {
+        Foo::foo(*self, a)
     }
 }
 
diff --git a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
index eb17aa78bd9..1164ef1a3c9 100644
--- a/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
+++ b/src/test/run-pass/monomorphized-callees-with-ty-params-3314.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::marker::MarkerTrait;
 
-trait Serializer {
+trait Serializer : MarkerTrait {
 }
 
 trait Serializable {
diff --git a/src/test/run-pass/overloaded-autoderef-vtable.rs b/src/test/run-pass/overloaded-autoderef-vtable.rs
index be2b309b821..d50f2efe0e7 100644
--- a/src/test/run-pass/overloaded-autoderef-vtable.rs
+++ b/src/test/run-pass/overloaded-autoderef-vtable.rs
@@ -11,7 +11,8 @@
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
-    helper: H
+    helper: H,
+    value: T
 }
 
 trait Helper<T> {
@@ -39,6 +40,7 @@ impl Foo {
 }
 
 pub fn main() {
-    let x: DerefWithHelper<Option<Foo>, Foo> = DerefWithHelper { helper: Some(Foo {x: 5}) };
+    let x: DerefWithHelper<Option<Foo>, Foo> =
+        DerefWithHelper { helper: Some(Foo {x: 5}), value: Foo { x: 2 } };
     assert!(x.foo() == 5);
 }
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index 2838909c1be..2ef9e08134c 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -12,10 +12,11 @@
 
 #![feature(unboxed_closures)]
 
+use std::marker::PhantomData;
 use std::ops::Fn;
 use std::ops::Add;
 
-struct G<A>;
+struct G<A>(PhantomData<A>);
 
 impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
     type Output = i32;
@@ -27,5 +28,5 @@ impl<'a, A: Add<i32, Output=i32>> Fn<(A,)> for G<A> {
 
 fn main() {
     // ICE trigger
-    G(1_i32);
+    (G(PhantomData))(1_i32);
 }
diff --git a/src/test/run-pass/parameterized-trait-with-bounds.rs b/src/test/run-pass/parameterized-trait-with-bounds.rs
index 840e58848a7..061c9168955 100644
--- a/src/test/run-pass/parameterized-trait-with-bounds.rs
+++ b/src/test/run-pass/parameterized-trait-with-bounds.rs
@@ -11,12 +11,12 @@
 #![allow(dead_code)]
 
 
-trait A<T> {}
-trait B<T, U> {}
-trait C<'a, U> {}
+trait A<T> { fn get(self) -> T; }
+trait B<T, U> { fn get(self) -> (T,U); }
+trait C<'a, U> { fn get(self) -> &'a U; }
 
 mod foo {
-    pub trait D<'a, T> {}
+    pub trait D<'a, T> { fn get(self) -> &'a T; }
 }
 
 fn foo1<T>(_: &(A<T> + Send)) {}
diff --git a/src/test/run-pass/privacy-ns.rs b/src/test/run-pass/privacy-ns.rs
index f3380352f5f..e9b8e694d60 100644
--- a/src/test/run-pass/privacy-ns.rs
+++ b/src/test/run-pass/privacy-ns.rs
@@ -19,6 +19,7 @@
 // public type, private value
 pub mod foo1 {
     pub trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
@@ -50,6 +51,7 @@ fn test_glob1() {
 // private type, public value
 pub mod foo2 {
     trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
@@ -81,6 +83,7 @@ fn test_glob2() {
 // public type, public value
 pub mod foo3 {
     pub trait Bar {
+        fn dummy(&self) { }
     }
     pub struct Baz;
 
diff --git a/src/test/run-pass/regions-assoc-type-static-bound.rs b/src/test/run-pass/regions-assoc-type-static-bound.rs
index 6b629a9035d..80ae371e509 100644
--- a/src/test/run-pass/regions-assoc-type-static-bound.rs
+++ b/src/test/run-pass/regions-assoc-type-static-bound.rs
@@ -11,7 +11,10 @@
 // Test that the compiler considers the 'static bound declared in the
 // trait. Issue #20890.
 
-trait Foo { type Value: 'static; }
+trait Foo {
+    type Value: 'static;
+    fn dummy(&self) { }
+}
 
 fn require_static<T: 'static>() {}
 
diff --git a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
index 0a95a89d57c..a06e0f6da78 100644
--- a/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
+++ b/src/test/run-pass/regions-bound-lists-feature-gate-2.rs
@@ -12,7 +12,9 @@
 
 #![feature(issue_5723_bootstrap)]
 
-trait Foo { }
+trait Foo {
+    fn dummy(&self) { }
+}
 
 fn foo<'a, 'b, 'c:'a+'b, 'd>() {
 }
diff --git a/src/test/run-pass/regions-bound-lists-feature-gate.rs b/src/test/run-pass/regions-bound-lists-feature-gate.rs
index c5baecf7272..996583dc6de 100644
--- a/src/test/run-pass/regions-bound-lists-feature-gate.rs
+++ b/src/test/run-pass/regions-bound-lists-feature-gate.rs
@@ -12,8 +12,9 @@
 
 #![feature(issue_5723_bootstrap)]
 
-
-trait Foo { }
+trait Foo {
+    fn dummy(&self) { }
+}
 
 fn foo<'a>(x: Box<Foo + 'a>) {
 }
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 978383c2447..bdc0d41c94e 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
@@ -14,6 +14,8 @@
 // lifetime parameters must be early bound in the type of the
 // associated item.
 
+use std::marker;
+
 pub enum Value<'v> {
     A(&'v str),
     B,
@@ -23,7 +25,9 @@ pub trait Decoder<'v> {
     fn read(&mut self) -> Value<'v>;
 }
 
-pub trait Decodable<'v, D: Decoder<'v>> {
+pub trait Decodable<'v, D: Decoder<'v>>
+    : marker::PhantomFn<(), &'v int>
+{
     fn decode(d: &mut D) -> Self;
 }
 
diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs
index 6fcfaf58a02..3f434a4838d 100644
--- a/src/test/run-pass/regions-early-bound-trait-param.rs
+++ b/src/test/run-pass/regions-early-bound-trait-param.rs
@@ -53,11 +53,11 @@ fn field_invoke2<'l, 'm, 'n>(x: &'n Struct2<'l,'m>) -> int {
     x.f.short()
 }
 
-trait MakerTrait<'o> {
+trait MakerTrait {
     fn mk() -> Self;
 }
 
-fn make_val<'p, T:MakerTrait<'p>>() -> T {
+fn make_val<T:MakerTrait>() -> T {
     MakerTrait::mk()
 }
 
@@ -80,7 +80,7 @@ impl<'s> Trait<'s> for (int,int) {
     }
 }
 
-impl<'t> MakerTrait<'t> for Box<Trait<'t>+'static> {
+impl<'t> MakerTrait for Box<Trait<'t>+'static> {
     fn mk() -> Box<Trait<'t>+'static> { box() (4,5) as Box<Trait> }
 }
 
diff --git a/src/test/run-pass/regions-issue-21422.rs b/src/test/run-pass/regions-issue-21422.rs
new file mode 100644
index 00000000000..c59bf15afc3
--- /dev/null
+++ b/src/test/run-pass/regions-issue-21422.rs
@@ -0,0 +1,25 @@
+// 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.
+
+// Regression test for issue #21422, which was related to failing to
+// add inference constraints that the operands of a binary operator
+// should outlive the binary operation itself.
+
+pub struct P<'a> {
+    _ptr: *const &'a u8,
+}
+
+impl <'a> PartialEq for P<'a> {
+    fn eq(&self, other: &P<'a>) -> bool {
+        (self as *const _) == (other as *const _)
+    }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
index d3464f01203..5964ac65d5f 100644
--- a/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
+++ b/src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
@@ -10,7 +10,9 @@
 
 #![feature(unsafe_destructor)]
 
-pub struct Foo<T>;
+use std::marker;
+
+pub struct Foo<T>(marker::PhantomData<T>);
 
 impl<T> Iterator for Foo<T> {
     type Item = T;
diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
index a35ab1bfc0c..80c478afa64 100644
--- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs
+++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
@@ -12,7 +12,9 @@
 // should not upset the variance inference for actual occurrences of
 // that lifetime in type expressions.
 
-pub trait HasLife<'a> { }
+pub trait HasLife<'a> {
+    fn dummy(&'a self) { } // just to induce a variance on 'a
+}
 
 trait UseLife01 {
     fn refs<'a, H: HasLife<'a>>(&'a self) -> H;
@@ -23,7 +25,11 @@ trait UseLife02 {
 }
 
 
-pub trait HasType<T> { }
+pub trait HasType<T>
+{
+    fn dummy(&self, t: T) -> T { panic!() }
+}
+
 
 trait UseLife03<T> {
     fn refs<'a, H: HasType<&'a T>>(&'a self) -> H;
diff --git a/src/test/run-pass/self-impl.rs b/src/test/run-pass/self-impl.rs
index 40a4dc52a70..af2b2de8ab8 100644
--- a/src/test/run-pass/self-impl.rs
+++ b/src/test/run-pass/self-impl.rs
@@ -29,6 +29,7 @@ pub struct Baz<X> {
 
 trait Bar<X> {
     fn bar(x: Self, y: &Self, z: Box<Self>) -> Self;
+    fn dummy(&self, x: X) { }
 }
 
 impl Bar<int> for Box<Baz<int>> {
diff --git a/src/test/run-pass/simple-match-generic-tag.rs b/src/test/run-pass/simple-match-generic-tag.rs
index 7ed8cb434ca..2217dddbd21 100644
--- a/src/test/run-pass/simple-match-generic-tag.rs
+++ b/src/test/run-pass/simple-match-generic-tag.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-
-enum opt<T> { none, }
+enum opt<T> { none, some(T) }
 
 pub fn main() {
     let x = opt::none::<int>;
-    match x { opt::none::<int> => { println!("hello world"); } }
+    match x {
+        opt::none::<int> => { println!("hello world"); }
+        opt::some(_) => { }
+    }
 }
diff --git a/src/test/run-pass/syntax-trait-polarity.rs b/src/test/run-pass/syntax-trait-polarity.rs
index 3344844d49f..340ad2a531a 100644
--- a/src/test/run-pass/syntax-trait-polarity.rs
+++ b/src/test/run-pass/syntax-trait-polarity.rs
@@ -10,17 +10,17 @@
 
 #![feature(optin_builtin_traits)]
 
-use std::marker::Send;
+use std::marker::{MarkerTrait, Send};
 
 struct TestType;
 
 impl TestType {}
 
-trait TestTrait {}
+trait TestTrait : MarkerTrait {}
 
 impl !Send for TestType {}
 
-struct TestType2<T>;
+struct TestType2<T>(T);
 
 impl<T> TestType2<T> {}
 
diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs
index b5ae259bc63..76c62a83e75 100644
--- a/src/test/run-pass/trailing-comma.rs
+++ b/src/test/run-pass/trailing-comma.rs
@@ -12,7 +12,7 @@
 
 fn f<T,>(_: T,) {}
 
-struct Foo<T,>;
+struct Foo<T,>(T);
 
 struct Bar;
 
@@ -34,7 +34,7 @@ pub fn main() {
     let [_, _, .., _,] = [1, 1, 1, 1,];
     let [_, _, _.., _,] = [1, 1, 1, 1,];
 
-    let x: Foo<int,> = Foo::<int,>;
+    let x: Foo<int,> = Foo::<int,>(1);
 
     Bar::f(0,);
     Bar.g(0,);
diff --git a/src/test/run-pass/trait-bounds-basic.rs b/src/test/run-pass/trait-bounds-basic.rs
index d03496403ad..ed25bf8b02e 100644
--- a/src/test/run-pass/trait-bounds-basic.rs
+++ b/src/test/run-pass/trait-bounds-basic.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-trait Foo {
+trait Foo : ::std::marker::MarkerTrait {
 }
 
 fn b(_x: Box<Foo+Send>) {
diff --git a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
index e3234f03754..976120908b2 100644
--- a/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/run-pass/trait-bounds-on-structs-and-enums.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait U {}
-trait T<X: U> {}
+trait U : ::std::marker::MarkerTrait {}
+trait T<X: U> { fn get(self) -> X; }
 
-trait S2<Y: U> {
+trait S2<Y: U> : ::std::marker::MarkerTrait {
     fn m(x: Box<T<Y>+'static>) {}
 }
 
diff --git a/src/test/run-pass/trait-bounds-recursion.rs b/src/test/run-pass/trait-bounds-recursion.rs
index 49f8999cd45..7135dad7d19 100644
--- a/src/test/run-pass/trait-bounds-recursion.rs
+++ b/src/test/run-pass/trait-bounds-recursion.rs
@@ -10,17 +10,17 @@
 
 trait I { fn i(&self) -> Self; }
 
-trait A<T:I> {
+trait A<T:I> : ::std::marker::MarkerTrait {
     fn id(x:T) -> T { x.i() }
 }
 
-trait J<T> { fn j(&self) -> Self; }
+trait J<T> { fn j(&self) -> T; }
 
-trait B<T:J<T>> {
+trait B<T:J<T>> : ::std::marker::MarkerTrait {
     fn id(x:T) -> T { x.j() }
 }
 
-trait C {
+trait C : ::std::marker::MarkerTrait {
     fn id<T:J<T>>(x:T) -> T { x.j() }
 }
 
diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs
index 3efe2507470..383849ca512 100644
--- a/src/test/run-pass/trait-default-method-bound-subst4.rs
+++ b/src/test/run-pass/trait-default-method-bound-subst4.rs
@@ -11,6 +11,7 @@
 
 trait A<T> {
     fn g(&self, x: uint) -> uint { x }
+    fn h(&self, x: T) { }
 }
 
 impl<T> A<T> for int { }
diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs
index 16ef315c206..bd2bf430a68 100644
--- a/src/test/run-pass/trait-impl.rs
+++ b/src/test/run-pass/trait-impl.rs
@@ -16,7 +16,8 @@ use traitimpl::Bar;
 
 static mut COUNT: uint = 1;
 
-trait T {}
+trait T : ::std::marker::MarkerTrait {
+}
 
 impl<'a> T+'a {
     fn foo(&self) {
diff --git a/src/test/run-pass/trait-inheritance-num2.rs b/src/test/run-pass/trait-inheritance-num2.rs
index 1e6e7227a06..f89eea46090 100644
--- a/src/test/run-pass/trait-inheritance-num2.rs
+++ b/src/test/run-pass/trait-inheritance-num2.rs
@@ -14,8 +14,7 @@
 use std::cmp::{PartialEq, PartialOrd};
 use std::num::NumCast;
 
-pub trait TypeExt {}
-
+pub trait TypeExt : ::std::marker::MarkerTrait { }
 
 impl TypeExt for u8 {}
 impl TypeExt for u16 {}
diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs
index 3b454aad03e..8f3b325a513 100644
--- a/src/test/run-pass/trait-inheritance-static2.rs
+++ b/src/test/run-pass/trait-inheritance-static2.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait MyEq { }
+pub trait MyEq : ::std::marker::MarkerTrait { }
 
-pub trait MyNum {
+pub trait MyNum : ::std::marker::MarkerTrait {
     fn from_int(int) -> Self;
 }
 
diff --git a/src/test/run-pass/trait-object-generics.rs b/src/test/run-pass/trait-object-generics.rs
index 76352c799a0..6f89490716f 100644
--- a/src/test/run-pass/trait-object-generics.rs
+++ b/src/test/run-pass/trait-object-generics.rs
@@ -13,11 +13,14 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
+use std::marker;
+
 pub trait Trait2<A> {
-    fn doit(&self);
+    fn doit(&self) -> A;
 }
 
 pub struct Impl<A1, A2, A3> {
+    m1: marker::PhantomData<(A1,A2,A3)>,
     /*
      * With A2 we get the ICE:
      * task <unnamed> failed at 'index out of bounds: the len is 1 but the index is 1',
@@ -28,13 +31,13 @@ pub struct Impl<A1, A2, A3> {
 
 impl<A1, A2, A3> Impl<A1, A2, A3> {
     pub fn step(&self) {
-        self.t.doit()
+        self.t.doit();
     }
 }
 
 // test for #8601
 
-enum Type<T> { Constant }
+enum Type<T> { Constant(T) }
 
 trait Trait<K,V> {
     fn method(&self,Type<(K,V)>) -> int;
@@ -46,5 +49,5 @@ impl<V> Trait<u8,V> for () {
 
 pub fn main() {
     let a = box() () as Box<Trait<u8, u8>>;
-    assert_eq!(a.method(Type::Constant), 0);
+    assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0);
 }
diff --git a/src/test/run-pass/trait-static-method-overwriting.rs b/src/test/run-pass/trait-static-method-overwriting.rs
index a8cea24db0c..10439d5c86a 100644
--- a/src/test/run-pass/trait-static-method-overwriting.rs
+++ b/src/test/run-pass/trait-static-method-overwriting.rs
@@ -10,7 +10,7 @@
 // except according to those terms.
 
 mod base {
-    pub trait HasNew<T> {
+    pub trait HasNew {
         fn new() -> Self;
     }
 
@@ -18,7 +18,7 @@ mod base {
         dummy: (),
     }
 
-    impl ::base::HasNew<Foo> for Foo {
+    impl ::base::HasNew for Foo {
         fn new() -> Foo {
             println!("Foo");
             Foo { dummy: () }
@@ -29,7 +29,7 @@ mod base {
         dummy: (),
     }
 
-    impl ::base::HasNew<Bar> for Bar {
+    impl ::base::HasNew for Bar {
         fn new() -> Bar {
             println!("Bar");
             Bar { dummy: () }
@@ -38,6 +38,6 @@ mod base {
 }
 
 pub fn main() {
-    let _f: base::Foo = base::HasNew::<base::Foo>::new();
-    let _b: base::Bar = base::HasNew::<base::Bar>::new();
+    let _f: base::Foo = base::HasNew::new();
+    let _b: base::Bar = base::HasNew::new();
 }
diff --git a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
index 1f9b821178c..2d1ba7f39b2 100644
--- a/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
+++ b/src/test/run-pass/unboxed-closures-infer-recursive-fn.rs
@@ -10,7 +10,7 @@
 
 #![feature(core,unboxed_closures)]
 
-use std::marker::CovariantType;
+use std::marker::PhantomData;
 
 // Test that we are able to infer a suitable kind for a "recursive"
 // closure.  As far as I can tell, coding up a recursive closure
@@ -20,12 +20,12 @@ use std::marker::CovariantType;
 
 struct YCombinator<F,A,R> {
     func: F,
-    marker: CovariantType<(A,R)>,
+    marker: PhantomData<(A,R)>,
 }
 
 impl<F,A,R> YCombinator<F,A,R> {
     fn new(f: F) -> YCombinator<F,A,R> {
-        YCombinator { func: f, marker: CovariantType }
+        YCombinator { func: f, marker: PhantomData }
     }
 }
 
diff --git a/src/test/run-pass/unique-object-move.rs b/src/test/run-pass/unique-object-move.rs
index cec523a0671..1d4eb0a7523 100644
--- a/src/test/run-pass/unique-object-move.rs
+++ b/src/test/run-pass/unique-object-move.rs
@@ -13,7 +13,7 @@
 #![allow(unknown_features)]
 #![feature(box_syntax)]
 
-pub trait EventLoop { }
+pub trait EventLoop : ::std::marker::MarkerTrait { }
 
 pub struct UvEventLoop {
     uvio: int
diff --git a/src/test/run-pass/unsized.rs b/src/test/run-pass/unsized.rs
index e6dd8d46952..ae175d27b0a 100644
--- a/src/test/run-pass/unsized.rs
+++ b/src/test/run-pass/unsized.rs
@@ -12,17 +12,19 @@
 
 // Test syntax checks for `?Sized` syntax.
 
-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>;
-enum E<X: ?Sized> {}
+use std::marker::{PhantomData, PhantomFn};
+
+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)> {}
+struct S1<X: ?Sized>(PhantomData<X>);
+enum E<X: ?Sized> { E1(PhantomData<X>) }
 impl <X: ?Sized> T1 for S1<X> {}
 fn f<X: ?Sized>() {}
 type TT<T: ?Sized> = T;
diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs
index 285100dd719..10b2f2fb709 100644
--- a/src/test/run-pass/unsized2.rs
+++ b/src/test/run-pass/unsized2.rs
@@ -15,6 +15,8 @@
 
 // Test sized-ness checking in substitution.
 
+use std::marker;
+
 // Unbounded.
 fn f1<X: ?Sized>(x: &X) {
     f1::<X>(x);
@@ -25,7 +27,7 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T {}
+trait T { fn dummy(&self) { } }
 fn f3<X: T+?Sized>(x: &X) {
     f3::<X>(x);
 }
@@ -66,20 +68,24 @@ fn f7<X: ?Sized+T3>(x: &X) {
 }
 
 trait T4<X> {
-    fn m1(x: &T4<X>);
-    fn m2(x: &T5<X>);
+    fn dummy(&self) { }
+    fn m1(x: &T4<X>, y: X);
+    fn m2(x: &T5<X>, y: X);
 }
 trait T5<X: ?Sized> {
+    fn dummy(&self) { }
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 
 trait T6<X: T> {
+    fn dummy(&self) { }
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
 }
 trait T7<X: ?Sized+T> {
+    fn dummy(&self) { }
     // not an error (for now)
     fn m1(x: &T4<X>);
     fn m2(x: &T5<X>);
diff --git a/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
new file mode 100644
index 00000000000..948d68e0ccd
--- /dev/null
+++ b/src/test/run-pass/variance-intersection-of-ref-and-opt-ref.rs
@@ -0,0 +1,34 @@
+// 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.
+
+// Elaborated version of the opening example from RFC 738. This failed
+// to compile before variance because invariance of `Option` prevented
+// us from approximating the lifetimes of `field1` and `field2` to a
+// common intersection.
+
+#![allow(dead_code)]
+
+struct List<'l> {
+    field1: &'l i32,
+    field2: Option<&'l i32>,
+}
+
+fn foo(field1: &i32, field2: Option<&i32>) -> i32 {
+    let list = List { field1: field1, field2: field2 };
+    *list.field1 + list.field2.cloned().unwrap_or(0)
+}
+
+fn main() {
+    let x = 22;
+    let y = Some(3);
+    let z = None;
+    assert_eq!(foo(&x, y.as_ref()), 25);
+    assert_eq!(foo(&x, z.as_ref()), 22);
+}
diff --git a/src/test/run-pass/variance-trait-matching.rs b/src/test/run-pass/variance-trait-matching.rs
new file mode 100644
index 00000000000..10441bee3cb
--- /dev/null
+++ b/src/test/run-pass/variance-trait-matching.rs
@@ -0,0 +1,49 @@
+// 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.
+
+#![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/variance-vec-covariant.rs b/src/test/run-pass/variance-vec-covariant.rs
new file mode 100644
index 00000000000..caec6df5a4d
--- /dev/null
+++ b/src/test/run-pass/variance-vec-covariant.rs
@@ -0,0 +1,28 @@
+// 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.
+
+// Test that vec is now covariant in its argument type.
+
+#![allow(dead_code)]
+
+fn foo<'a,'b>(v1: Vec<&'a i32>, v2: Vec<&'b i32>) -> i32 {
+    bar(v1, v2).cloned().unwrap_or(0) // only type checks if we can intersect 'a and 'b
+}
+
+fn bar<'c>(v1: Vec<&'c i32>, v2: Vec<&'c i32>) -> Option<&'c i32> {
+    v1.get(0).cloned().or_else(|| v2.get(0).cloned())
+}
+
+fn main() {
+    let x = 22;
+    let y = 44;
+    assert_eq!(foo(vec![&x], vec![&y]), 22);
+    assert_eq!(foo(vec![&y], vec![&x]), 44);
+}
diff --git a/src/test/run-pass/visible-private-types-feature-gate.rs b/src/test/run-pass/visible-private-types-feature-gate.rs
index 9518671b479..46e93b25697 100644
--- a/src/test/run-pass/visible-private-types-feature-gate.rs
+++ b/src/test/run-pass/visible-private-types-feature-gate.rs
@@ -10,7 +10,7 @@
 
 #![feature(visible_private_types)]
 
-trait Foo {}
+trait Foo { fn dummy(&self) { } }
 
 pub trait Bar : Foo {}
 
diff --git a/src/test/run-pass/where-clause-bounds-inconsistency.rs b/src/test/run-pass/where-clause-bounds-inconsistency.rs
index a1a61127f68..3374f47ed5f 100644
--- a/src/test/run-pass/where-clause-bounds-inconsistency.rs
+++ b/src/test/run-pass/where-clause-bounds-inconsistency.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Bound {}
+trait Bound {
+    fn dummy(&self) { }
+}
 
 trait Trait {
     fn a<T>(&self, T) where T: Bound;
diff --git a/src/test/run-pass/where-clause-early-bound-lifetimes.rs b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
index cade99b83a2..4a149d4d3df 100644
--- a/src/test/run-pass/where-clause-early-bound-lifetimes.rs
+++ b/src/test/run-pass/where-clause-early-bound-lifetimes.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait TheTrait { }
+trait TheTrait { fn dummy(&self) { } }
 
 impl TheTrait for &'static int { }
 
diff --git a/src/test/run-pass/where-clause-method-substituion.rs b/src/test/run-pass/where-clause-method-substituion.rs
index b391df8500b..ecc210ea579 100644
--- a/src/test/run-pass/where-clause-method-substituion.rs
+++ b/src/test/run-pass/where-clause-method-substituion.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Foo<T> {}
+trait Foo<T> { fn dummy(&self, arg: T) { } }
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
@@ -19,7 +19,7 @@ struct X;
 
 impl Foo<S> for X {}
 
-impl Bar<X> for int {
+impl Bar<X> for i32 {
     fn method<U>(&self) where X: Foo<U> {
     }
 }
diff --git a/src/test/run-pass/where-for-self.rs b/src/test/run-pass/where-for-self.rs
index 5d426793c2e..1fd223b0dd3 100644
--- a/src/test/run-pass/where-for-self.rs
+++ b/src/test/run-pass/where-for-self.rs
@@ -11,13 +11,19 @@
 // Test that we can quantify lifetimes outside a constraint (i.e., including
 // the self type) in a where clause.
 
+use std::marker::PhantomFn;
+
 static mut COUNT: u32 = 1;
 
-trait Bar<'a> {
+trait Bar<'a>
+    : PhantomFn<&'a ()>
+{
     fn bar(&self);
 }
 
-trait Baz<'a> {
+trait Baz<'a>
+    : PhantomFn<&'a ()>
+{
     fn baz(&self);
 }