summaryrefslogtreecommitdiffstats
path: root/src/test/ui/associated-types
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/associated-types
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/associated-types')
-rw-r--r--src/test/ui/associated-types/associate-type-bound-normalization.rs25
-rw-r--r--src/test/ui/associated-types/associated-item-long-paths.rs47
-rw-r--r--src/test/ui/associated-types/associated-type-destructuring-assignment.rs10
-rw-r--r--src/test/ui/associated-types/associated-type-macro.rs4
-rw-r--r--src/test/ui/associated-types/associated-type-macro.stderr8
-rw-r--r--src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs42
-rw-r--r--src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.stderr129
-rw-r--r--src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs43
-rw-r--r--src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr100
-rw-r--r--src/test/ui/associated-types/associated-type-projection-from-supertrait.rs36
-rw-r--r--src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr59
-rw-r--r--src/test/ui/associated-types/associated-type-struct-construction.rs24
-rw-r--r--src/test/ui/associated-types/associated-type-tuple-struct-construction.rs24
-rw-r--r--src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr19
-rw-r--r--src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs25
-rw-r--r--src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr9
-rw-r--r--src/test/ui/associated-types/associated-types-basic.rs14
-rw-r--r--src/test/ui/associated-types/associated-types-binding-in-trait.rs36
-rw-r--r--src/test/ui/associated-types/associated-types-binding-in-where-clause.rs38
-rw-r--r--src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr37
-rw-r--r--src/test/ui/associated-types/associated-types-bound-ambiguity.rs23
-rw-r--r--src/test/ui/associated-types/associated-types-bound-failure.fixed29
-rw-r--r--src/test/ui/associated-types/associated-types-bound-failure.rs29
-rw-r--r--src/test/ui/associated-types/associated-types-bound-failure.stderr16
-rw-r--r--src/test/ui/associated-types/associated-types-bound.rs43
-rw-r--r--src/test/ui/associated-types/associated-types-cc.rs18
-rw-r--r--src/test/ui/associated-types/associated-types-coherence-failure.rs49
-rw-r--r--src/test/ui/associated-types/associated-types-coherence-failure.stderr21
-rw-r--r--src/test/ui/associated-types/associated-types-conditional-dispatch.rs66
-rw-r--r--src/test/ui/associated-types/associated-types-constant-type.rs31
-rw-r--r--src/test/ui/associated-types/associated-types-doubleendediterator-object.rs19
-rw-r--r--src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs17
-rw-r--r--src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs21
-rw-r--r--src/test/ui/associated-types/associated-types-enum-field-named.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-enum-field-numbered.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-eq-1.rs13
-rw-r--r--src/test/ui/associated-types/associated-types-eq-1.stderr20
-rw-r--r--src/test/ui/associated-types/associated-types-eq-2.rs19
-rw-r--r--src/test/ui/associated-types/associated-types-eq-2.stderr9
-rw-r--r--src/test/ui/associated-types/associated-types-eq-3.rs42
-rw-r--r--src/test/ui/associated-types/associated-types-eq-3.stderr49
-rw-r--r--src/test/ui/associated-types/associated-types-eq-expr-path.rs16
-rw-r--r--src/test/ui/associated-types/associated-types-eq-expr-path.stderr9
-rw-r--r--src/test/ui/associated-types/associated-types-eq-hr.rs111
-rw-r--r--src/test/ui/associated-types/associated-types-eq-hr.stderr47
-rw-r--r--src/test/ui/associated-types/associated-types-eq-obj.rs25
-rw-r--r--src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed15
-rw-r--r--src/test/ui/associated-types/associated-types-for-unimpl-trait.rs15
-rw-r--r--src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr14
-rw-r--r--src/test/ui/associated-types/associated-types-from-supertrait.rs8
-rw-r--r--src/test/ui/associated-types/associated-types-impl-redirect.rs51
-rw-r--r--src/test/ui/associated-types/associated-types-in-ambiguous-context.rs29
-rw-r--r--src/test/ui/associated-types/associated-types-in-ambiguous-context.stderr33
-rw-r--r--src/test/ui/associated-types/associated-types-in-bound-type-arg.rs17
-rw-r--r--src/test/ui/associated-types/associated-types-in-default-method.rs27
-rw-r--r--src/test/ui/associated-types/associated-types-in-fn.rs28
-rw-r--r--src/test/ui/associated-types/associated-types-in-impl-generics.rs36
-rw-r--r--src/test/ui/associated-types/associated-types-in-inherent-method.rs30
-rw-r--r--src/test/ui/associated-types/associated-types-incomplete-object.rs31
-rw-r--r--src/test/ui/associated-types/associated-types-incomplete-object.stderr32
-rw-r--r--src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs14
-rw-r--r--src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr14
-rw-r--r--src/test/ui/associated-types/associated-types-issue-17359.rs10
-rw-r--r--src/test/ui/associated-types/associated-types-issue-17359.stderr12
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20220.rs28
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20346.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20346.stderr25
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20371.rs9
-rw-r--r--src/test/ui/associated-types/associated-types-issue-21212.rs22
-rw-r--r--src/test/ui/associated-types/associated-types-iterator-binding.rs19
-rw-r--r--src/test/ui/associated-types/associated-types-method.rs28
-rw-r--r--src/test/ui/associated-types/associated-types-multiple-types-one-trait.rs46
-rw-r--r--src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr39
-rw-r--r--src/test/ui/associated-types/associated-types-nested-projections.rs44
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-bound.rs16
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-bound.stderr14
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.rs21
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr14
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait.rs26
-rw-r--r--src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr20
-rw-r--r--src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs38
-rw-r--r--src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-normalize-in-bounds.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs24
-rw-r--r--src/test/ui/associated-types/associated-types-outlives.rs28
-rw-r--r--src/test/ui/associated-types/associated-types-outlives.stderr13
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding-2.rs8
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding-2.stderr11
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding.rs11
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding.stderr27
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-default.rs22
-rw-r--r--src/test/ui/associated-types/associated-types-path-1.rs13
-rw-r--r--src/test/ui/associated-types/associated-types-path-1.stderr31
-rw-r--r--src/test/ui/associated-types/associated-types-path-2.rs46
-rw-r--r--src/test/ui/associated-types/associated-types-path-2.stderr79
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs27
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr30
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed37
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs37
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr14
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs39
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr54
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed38
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs38
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr25
-rw-r--r--src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs98
-rw-r--r--src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs16
-rw-r--r--src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs23
-rw-r--r--src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs38
-rw-r--r--src/test/ui/associated-types/associated-types-projection-in-object-type.rs40
-rw-r--r--src/test/ui/associated-types/associated-types-projection-in-supertrait.rs45
-rw-r--r--src/test/ui/associated-types/associated-types-projection-in-where-clause.rs31
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed30
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs30
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr14
-rw-r--r--src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs9
-rw-r--r--src/test/ui/associated-types/associated-types-ref-from-struct.rs51
-rw-r--r--src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs23
-rw-r--r--src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs21
-rw-r--r--src/test/ui/associated-types/associated-types-resolve-lifetime.rs15
-rw-r--r--src/test/ui/associated-types/associated-types-return.rs46
-rw-r--r--src/test/ui/associated-types/associated-types-simple.rs24
-rw-r--r--src/test/ui/associated-types/associated-types-stream.rs38
-rw-r--r--src/test/ui/associated-types/associated-types-struct-field-named.rs35
-rw-r--r--src/test/ui/associated-types/associated-types-struct-field-numbered.rs32
-rw-r--r--src/test/ui/associated-types/associated-types-subtyping-1.rs49
-rw-r--r--src/test/ui/associated-types/associated-types-subtyping-1.stderr28
-rw-r--r--src/test/ui/associated-types/associated-types-sugar-path.rs41
-rw-r--r--src/test/ui/associated-types/associated-types-unconstrained.rs16
-rw-r--r--src/test/ui/associated-types/associated-types-unconstrained.stderr12
-rw-r--r--src/test/ui/associated-types/associated-types-unsized.fixed14
-rw-r--r--src/test/ui/associated-types/associated-types-unsized.rs14
-rw-r--r--src/test/ui/associated-types/associated-types-unsized.stderr17
-rw-r--r--src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs46
-rw-r--r--src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs16
-rw-r--r--src/test/ui/associated-types/bound-lifetime-constrained.clause.stderr15
-rw-r--r--src/test/ui/associated-types/bound-lifetime-constrained.func.stderr15
-rw-r--r--src/test/ui/associated-types/bound-lifetime-constrained.object.stderr15
-rw-r--r--src/test/ui/associated-types/bound-lifetime-constrained.rs48
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.angle.stderr27
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr15
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr8
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.paren.stderr27
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-binding-only.rs71
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr15
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.local.stderr9
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr8
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.rs49
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.sig.stderr15
-rw-r--r--src/test/ui/associated-types/bound-lifetime-in-return-only.structure.stderr9
-rw-r--r--src/test/ui/associated-types/cache/chrono-scan.rs30
-rw-r--r--src/test/ui/associated-types/cache/elision.rs23
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr30
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs50
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr10
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr36
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr36
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.rs64
-rw-r--r--src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr15
-rw-r--r--src/test/ui/associated-types/default-associated-types.rs23
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-1.rs40
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-1.stderr15
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-2.rs41
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-fail-2.stderr15
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-pass-1.rs56
-rw-r--r--src/test/ui/associated-types/defaults-cyclic-pass-2.rs56
-rw-r--r--src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs37
-rw-r--r--src/test/ui/associated-types/defaults-in-other-trait-items.rs47
-rw-r--r--src/test/ui/associated-types/defaults-in-other-trait-items.stderr29
-rw-r--r--src/test/ui/associated-types/defaults-mixed.rs34
-rw-r--r--src/test/ui/associated-types/defaults-mixed.stderr21
-rw-r--r--src/test/ui/associated-types/defaults-specialization.rs96
-rw-r--r--src/test/ui/associated-types/defaults-specialization.stderr156
-rw-r--r--src/test/ui/associated-types/defaults-suitability.rs101
-rw-r--r--src/test/ui/associated-types/defaults-suitability.stderr135
-rw-r--r--src/test/ui/associated-types/defaults-unsound-62211-1.rs54
-rw-r--r--src/test/ui/associated-types/defaults-unsound-62211-1.stderr68
-rw-r--r--src/test/ui/associated-types/defaults-unsound-62211-2.rs54
-rw-r--r--src/test/ui/associated-types/defaults-unsound-62211-2.stderr68
-rw-r--r--src/test/ui/associated-types/defaults-wf.rs11
-rw-r--r--src/test/ui/associated-types/defaults-wf.stderr16
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.bad.stderr17
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.badbase.stderr17
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.badnll.stderr2
-rw-r--r--src/test/ui/associated-types/higher-ranked-projection.rs25
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-1.rs18
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-1.stderr19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-2.rs20
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-2.stderr18
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-object.rs14
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-object.stderr18
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-1.rs20
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-1.stderr19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-2.rs21
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr51
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-3.rs19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-3.stderr19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-4.rs19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-4.stderr19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-5.rs37
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr35
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-6.rs19
-rw-r--r--src/test/ui/associated-types/hr-associated-type-bound-param-6.stderr14
-rw-r--r--src/test/ui/associated-types/hr-associated-type-projection-1.rs20
-rw-r--r--src/test/ui/associated-types/hr-associated-type-projection-1.stderr24
-rw-r--r--src/test/ui/associated-types/impl-trait-return-missing-constraint.rs32
-rw-r--r--src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr24
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.rs27
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-1.stderr17
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.rs15
-rw-r--r--src/test/ui/associated-types/impl-wf-cycle-2.stderr15
-rw-r--r--src/test/ui/associated-types/issue-18655.rs22
-rw-r--r--src/test/ui/associated-types/issue-19081.rs14
-rw-r--r--src/test/ui/associated-types/issue-19883.rs16
-rw-r--r--src/test/ui/associated-types/issue-19883.stderr15
-rw-r--r--src/test/ui/associated-types/issue-20005.rs15
-rw-r--r--src/test/ui/associated-types/issue-20005.stderr23
-rw-r--r--src/test/ui/associated-types/issue-20825-2.rs10
-rw-r--r--src/test/ui/associated-types/issue-20825.rs10
-rw-r--r--src/test/ui/associated-types/issue-20825.stderr16
-rw-r--r--src/test/ui/associated-types/issue-21363.rs15
-rw-r--r--src/test/ui/associated-types/issue-21726.rs38
-rw-r--r--src/test/ui/associated-types/issue-22037.rs17
-rw-r--r--src/test/ui/associated-types/issue-22037.stderr14
-rw-r--r--src/test/ui/associated-types/issue-22066.rs12
-rw-r--r--src/test/ui/associated-types/issue-22560.rs15
-rw-r--r--src/test/ui/associated-types/issue-22560.stderr56
-rw-r--r--src/test/ui/associated-types/issue-22828.rs23
-rw-r--r--src/test/ui/associated-types/issue-23208.rs26
-rw-r--r--src/test/ui/associated-types/issue-23595-1.rs14
-rw-r--r--src/test/ui/associated-types/issue-23595-1.stderr13
-rw-r--r--src/test/ui/associated-types/issue-23595-2.rs10
-rw-r--r--src/test/ui/associated-types/issue-23595-2.stderr9
-rw-r--r--src/test/ui/associated-types/issue-24159.rs37
-rw-r--r--src/test/ui/associated-types/issue-24204.rs25
-rw-r--r--src/test/ui/associated-types/issue-24338.rs21
-rw-r--r--src/test/ui/associated-types/issue-25339.rs31
-rw-r--r--src/test/ui/associated-types/issue-26681.rs20
-rw-r--r--src/test/ui/associated-types/issue-26681.stderr14
-rw-r--r--src/test/ui/associated-types/issue-27675-unchecked-bounds.rs19
-rw-r--r--src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr21
-rw-r--r--src/test/ui/associated-types/issue-28871.rs24
-rw-r--r--src/test/ui/associated-types/issue-31597.rs29
-rw-r--r--src/test/ui/associated-types/issue-32350.rs29
-rw-r--r--src/test/ui/associated-types/issue-36499.rs5
-rw-r--r--src/test/ui/associated-types/issue-36499.stderr14
-rw-r--r--src/test/ui/associated-types/issue-37808.rs19
-rw-r--r--src/test/ui/associated-types/issue-37883.rs25
-rw-r--r--src/test/ui/associated-types/issue-38917.rs25
-rw-r--r--src/test/ui/associated-types/issue-39532.rs14
-rw-r--r--src/test/ui/associated-types/issue-40093.rs14
-rw-r--r--src/test/ui/associated-types/issue-41868.rs23
-rw-r--r--src/test/ui/associated-types/issue-43475.rs10
-rw-r--r--src/test/ui/associated-types/issue-43784-associated-type.rs17
-rw-r--r--src/test/ui/associated-types/issue-43784-associated-type.stderr19
-rw-r--r--src/test/ui/associated-types/issue-43924.rs16
-rw-r--r--src/test/ui/associated-types/issue-43924.stderr22
-rw-r--r--src/test/ui/associated-types/issue-44153.rs19
-rw-r--r--src/test/ui/associated-types/issue-44153.stderr20
-rw-r--r--src/test/ui/associated-types/issue-47139-1.rs78
-rw-r--r--src/test/ui/associated-types/issue-47139-2.rs66
-rw-r--r--src/test/ui/associated-types/issue-47385.rs16
-rw-r--r--src/test/ui/associated-types/issue-47814.rs13
-rw-r--r--src/test/ui/associated-types/issue-47814.stderr14
-rw-r--r--src/test/ui/associated-types/issue-48010.rs23
-rw-r--r--src/test/ui/associated-types/issue-48551.rs34
-rw-r--r--src/test/ui/associated-types/issue-50301.rs31
-rw-r--r--src/test/ui/associated-types/issue-54108.rs41
-rw-r--r--src/test/ui/associated-types/issue-54108.stderr20
-rw-r--r--src/test/ui/associated-types/issue-54182-1.rs92
-rw-r--r--src/test/ui/associated-types/issue-54182-2.rs19
-rw-r--r--src/test/ui/associated-types/issue-54467.rs46
-rw-r--r--src/test/ui/associated-types/issue-55846.rs39
-rw-r--r--src/test/ui/associated-types/issue-59324.rs26
-rw-r--r--src/test/ui/associated-types/issue-59324.stderr65
-rw-r--r--src/test/ui/associated-types/issue-62200.rs15
-rw-r--r--src/test/ui/associated-types/issue-62200.stderr11
-rw-r--r--src/test/ui/associated-types/issue-63591.rs24
-rw-r--r--src/test/ui/associated-types/issue-63593.rs13
-rw-r--r--src/test/ui/associated-types/issue-63593.stderr19
-rw-r--r--src/test/ui/associated-types/issue-64848.rs29
-rw-r--r--src/test/ui/associated-types/issue-64855-2.rs5
-rw-r--r--src/test/ui/associated-types/issue-64855.rs8
-rw-r--r--src/test/ui/associated-types/issue-64855.stderr9
-rw-r--r--src/test/ui/associated-types/issue-65774-1.rs58
-rw-r--r--src/test/ui/associated-types/issue-65774-1.stderr30
-rw-r--r--src/test/ui/associated-types/issue-65774-2.rs58
-rw-r--r--src/test/ui/associated-types/issue-65774-2.stderr25
-rw-r--r--src/test/ui/associated-types/issue-65934.rs17
-rw-r--r--src/test/ui/associated-types/issue-67684.rs62
-rw-r--r--src/test/ui/associated-types/issue-69398.rs21
-rw-r--r--src/test/ui/associated-types/issue-71113.rs16
-rw-r--r--src/test/ui/associated-types/issue-72806.rs21
-rw-r--r--src/test/ui/associated-types/issue-72806.stderr20
-rw-r--r--src/test/ui/associated-types/issue-76179.rs19
-rw-r--r--src/test/ui/associated-types/issue-82079.rs124
-rw-r--r--src/test/ui/associated-types/issue-85103.rs9
-rw-r--r--src/test/ui/associated-types/issue-85103.stderr8
-rw-r--r--src/test/ui/associated-types/issue-87261.rs99
-rw-r--r--src/test/ui/associated-types/issue-87261.stderr266
-rw-r--r--src/test/ui/associated-types/issue-88856.rs32
-rw-r--r--src/test/ui/associated-types/issue-91069.rs24
-rw-r--r--src/test/ui/associated-types/issue-91231.rs17
-rw-r--r--src/test/ui/associated-types/issue-91234.rs13
-rw-r--r--src/test/ui/associated-types/missing-associated-types.rs27
-rw-r--r--src/test/ui/associated-types/missing-associated-types.stderr129
-rw-r--r--src/test/ui/associated-types/normalization-debruijn-1.rs36
-rw-r--r--src/test/ui/associated-types/normalization-debruijn-2.rs31
-rw-r--r--src/test/ui/associated-types/normalization-debruijn-3.rs41
-rw-r--r--src/test/ui/associated-types/normalization-generality-2.rs30
-rw-r--r--src/test/ui/associated-types/normalization-generality.rs36
-rw-r--r--src/test/ui/associated-types/normalization-probe-cycle.rs25
-rw-r--r--src/test/ui/associated-types/normalize-cycle-in-eval-no-region.rs20
-rw-r--r--src/test/ui/associated-types/normalize-cycle-in-eval.rs43
-rw-r--r--src/test/ui/associated-types/object-method-numbering.rs28
-rw-r--r--src/test/ui/associated-types/object-normalization.rs26
-rw-r--r--src/test/ui/associated-types/param-env-normalize-cycle.rs39
-rw-r--r--src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs33
-rw-r--r--src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr45
-rw-r--r--src/test/ui/associated-types/point-at-type-on-obligation-failure.rs21
-rw-r--r--src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr20
-rw-r--r--src/test/ui/associated-types/project-defer-unification.rs104
-rw-r--r--src/test/ui/associated-types/project-recursion-limit-non-fatal.rs58
-rw-r--r--src/test/ui/associated-types/substs-ppaux.normal.stderr89
-rw-r--r--src/test/ui/associated-types/substs-ppaux.rs52
-rw-r--r--src/test/ui/associated-types/substs-ppaux.verbose.stderr89
-rw-r--r--src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs11
-rw-r--r--src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr19
-rw-r--r--src/test/ui/associated-types/wf-cycle-2.rs18
-rw-r--r--src/test/ui/associated-types/wf-cycle.rs13
332 files changed, 10265 insertions, 0 deletions
diff --git a/src/test/ui/associated-types/associate-type-bound-normalization.rs b/src/test/ui/associated-types/associate-type-bound-normalization.rs
new file mode 100644
index 000000000..db092970f
--- /dev/null
+++ b/src/test/ui/associated-types/associate-type-bound-normalization.rs
@@ -0,0 +1,25 @@
+// Make sure that we normalize bounds on associated types before checking them
+// as candidates.
+
+// check-pass
+
+trait Mul<T> {
+ type Output;
+}
+
+trait Matrix: Mul<<Self as Matrix>::Row, Output = ()> {
+ type Row;
+
+ type Transpose: Matrix<Row = Self::Row>;
+}
+
+fn is_mul<S, T: Mul<S, Output = ()>>() {}
+
+fn f<T: Matrix>() {
+ // The unnormalized bound on `T::Transpose` is
+ // `Mul<<T::Transpose as Matrix>::Row` which has to be normalized to be
+ // equal to `T::Row`.
+ is_mul::<T::Row, T::Transpose>();
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-item-long-paths.rs b/src/test/ui/associated-types/associated-item-long-paths.rs
new file mode 100644
index 000000000..aad8c487c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-item-long-paths.rs
@@ -0,0 +1,47 @@
+// run-pass
+
+use std::mem::size_of;
+
+// The main point of this test is to ensure that we can parse and resolve
+// associated items on associated types.
+
+trait Foo {
+ type U;
+}
+
+trait Bar {
+ // Note 1: Chains of associated items in a path won't type-check.
+ // Note 2: Associated consts can't depend on type parameters or `Self`,
+ // which are the only types that an associated type can be referenced on for
+ // now, so we can only test methods.
+ fn method() -> u32;
+ fn generic_method<T>() -> usize;
+}
+
+struct MyFoo;
+struct MyBar;
+
+impl Foo for MyFoo {
+ type U = MyBar;
+}
+
+impl Bar for MyBar {
+ fn method() -> u32 {
+ 2u32
+ }
+ fn generic_method<T>() -> usize {
+ size_of::<T>()
+ }
+}
+
+fn foo<T>()
+ where T: Foo,
+ T::U: Bar,
+{
+ assert_eq!(2u32, <T as Foo>::U::method());
+ assert_eq!(8usize, <T as Foo>::U::generic_method::<f64>());
+}
+
+fn main() {
+ foo::<MyFoo>();
+}
diff --git a/src/test/ui/associated-types/associated-type-destructuring-assignment.rs b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
new file mode 100644
index 000000000..f038c9ce7
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-destructuring-assignment.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+#![feature(more_qualified_paths)]
+
+enum E { V() }
+
+fn main() {
+ <E>::V() = E::V(); // OK, destructuring assignment
+ <E>::V {} = E::V(); // OK, destructuring assignment
+}
diff --git a/src/test/ui/associated-types/associated-type-macro.rs b/src/test/ui/associated-types/associated-type-macro.rs
new file mode 100644
index 000000000..22b5bca40
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-macro.rs
@@ -0,0 +1,4 @@
+fn main() {
+ #[cfg(FALSE)]
+ <() as module>::mac!(); //~ ERROR macros cannot use qualified paths
+}
diff --git a/src/test/ui/associated-types/associated-type-macro.stderr b/src/test/ui/associated-types/associated-type-macro.stderr
new file mode 100644
index 000000000..6a4cf99c4
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-macro.stderr
@@ -0,0 +1,8 @@
+error: macros cannot use qualified paths
+ --> $DIR/associated-type-macro.rs:3:5
+ |
+LL | <() as module>::mac!();
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs b/src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs
new file mode 100644
index 000000000..c85d41c7f
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs
@@ -0,0 +1,42 @@
+// Test equality constraints in a where clause where the type being
+// equated appears in a supertrait.
+
+pub trait Vehicle {
+ type Color;
+
+ fn go(&self) { }
+}
+
+pub trait Box {
+ type Color;
+
+ fn mail(&self) { }
+}
+
+fn a<C:Vehicle+Box>(_: C::Color) {
+ //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+fn b<C>(_: C::Color) where C : Vehicle+Box {
+ //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+fn c<C>(_: C::Color) where C : Vehicle, C : Box {
+ //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+struct D<X>;
+impl<X> D<X> where X : Vehicle {
+ fn d(&self, _: X::Color) where X : Box { }
+ //~^ ERROR ambiguous associated type `Color` in bounds of `X`
+}
+
+trait E<X:Vehicle> {
+ fn e(&self, _: X::Color) where X : Box;
+ //~^ ERROR ambiguous associated type `Color` in bounds of `X`
+
+ fn f(&self, _: X::Color) where X : Box { }
+ //~^ ERROR ambiguous associated type `Color` in bounds of `X`
+}
+
+pub fn main() { }
diff --git a/src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.stderr b/src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.stderr
new file mode 100644
index 000000000..236552baf
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.stderr
@@ -0,0 +1,129 @@
+error[E0221]: ambiguous associated type `Color` in bounds of `C`
+ --> $DIR/associated-type-projection-ambig-between-bound-and-where-clause.rs:16:24
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn a<C:Vehicle+Box>(_: C::Color) {
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn a<C:Vehicle+Box>(_: <C as Box>::Color) {
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn a<C:Vehicle+Box>(_: <C as Vehicle>::Color) {
+ | ~~~~~~~~~~~~~~~~
+
+error[E0221]: ambiguous associated type `Color` in bounds of `C`
+ --> $DIR/associated-type-projection-ambig-between-bound-and-where-clause.rs:20:12
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn b<C>(_: C::Color) where C : Vehicle+Box {
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn b<C>(_: <C as Box>::Color) where C : Vehicle+Box {
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn b<C>(_: <C as Vehicle>::Color) where C : Vehicle+Box {
+ | ~~~~~~~~~~~~~~~~
+
+error[E0221]: ambiguous associated type `Color` in bounds of `C`
+ --> $DIR/associated-type-projection-ambig-between-bound-and-where-clause.rs:24:12
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn c<C>(_: C::Color) where C : Vehicle, C : Box {
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn c<C>(_: <C as Box>::Color) where C : Vehicle, C : Box {
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn c<C>(_: <C as Vehicle>::Color) where C : Vehicle, C : Box {
+ | ~~~~~~~~~~~~~~~~
+
+error[E0221]: ambiguous associated type `Color` in bounds of `X`
+ --> $DIR/associated-type-projection-ambig-between-bound-and-where-clause.rs:35:20
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn e(&self, _: X::Color) where X : Box;
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn e(&self, _: <X as Box>::Color) where X : Box;
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn e(&self, _: <X as Vehicle>::Color) where X : Box;
+ | ~~~~~~~~~~~~~~~~
+
+error[E0221]: ambiguous associated type `Color` in bounds of `X`
+ --> $DIR/associated-type-projection-ambig-between-bound-and-where-clause.rs:38:20
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn f(&self, _: X::Color) where X : Box { }
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn f(&self, _: <X as Box>::Color) where X : Box { }
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn f(&self, _: <X as Vehicle>::Color) where X : Box { }
+ | ~~~~~~~~~~~~~~~~
+
+error[E0221]: ambiguous associated type `Color` in bounds of `X`
+ --> $DIR/associated-type-projection-ambig-between-bound-and-where-clause.rs:30:20
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn d(&self, _: X::Color) where X : Box { }
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn d(&self, _: <X as Box>::Color) where X : Box { }
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn d(&self, _: <X as Vehicle>::Color) where X : Box { }
+ | ~~~~~~~~~~~~~~~~
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0221`.
diff --git a/src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs b/src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs
new file mode 100644
index 000000000..df19332b6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs
@@ -0,0 +1,43 @@
+// Test equality constraints in a where clause where the type being
+// equated appears in a supertrait.
+
+pub trait Vehicle {
+ type Color;
+
+ fn go(&self) { }
+}
+
+pub trait Box {
+ type Color;
+ //
+ fn mail(&self) { }
+}
+
+pub trait BoxCar : Box + Vehicle {
+}
+
+fn dent<C:BoxCar>(c: C, color: C::Color) {
+ //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
+ //~^ ERROR ambiguous associated type
+ //~| ERROR the value of the associated types
+}
+
+fn paint<C:BoxCar>(c: C, d: C::Color) {
+ //~^ ERROR ambiguous associated type `Color` in bounds of `C`
+}
+
+fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
+ //~^ ERROR the value of the associated types
+ //~| ERROR equality constraints are not yet supported in `where` clauses
+}
+
+fn dent_object_3<X, COLOR>(c: X)
+where X: BoxCar,
+ X: Vehicle<Color = COLOR>,
+ X: Box<Color = COLOR>
+{} // OK!
+
+pub fn main() { }
diff --git a/src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr
new file mode 100644
index 000000000..e765f9323
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr
@@ -0,0 +1,100 @@
+error: equality constraints are not yet supported in `where` clauses
+ --> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:46
+ |
+LL | fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported
+ |
+ = note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
+
+error[E0221]: ambiguous associated type `Color` in bounds of `C`
+ --> $DIR/associated-type-projection-from-multiple-supertraits.rs:19:32
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn dent<C:BoxCar>(c: C, color: C::Color) {
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn dent<C:BoxCar>(c: C, color: <C as Vehicle>::Color) {
+ | ~~~~~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn dent<C:BoxCar>(c: C, color: <C as Box>::Color) {
+ | ~~~~~~~~~~~~
+
+error[E0222]: ambiguous associated type `Color` in bounds of `BoxCar`
+ --> $DIR/associated-type-projection-from-multiple-supertraits.rs:23:37
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
+ | ^^^^^^^^^^^ ambiguous associated type `Color`
+ |
+ = help: consider introducing a new type parameter `T` and adding `where` constraints:
+ where
+ T: BoxCar,
+ T: Vehicle::Color = COLOR,
+ T: Box::Color = COLOR
+
+error[E0191]: the value of the associated types `Color` (from trait `Box`), `Color` (from trait `Vehicle`) must be specified
+ --> $DIR/associated-type-projection-from-multiple-supertraits.rs:23:30
+ |
+LL | type Color;
+ | ---------- `Vehicle::Color` defined here
+...
+LL | type Color;
+ | ---------- `Box::Color` defined here
+...
+LL | fn dent_object<COLOR>(c: dyn BoxCar<Color=COLOR>) {
+ | ^^^^^^^^^^^^^^^^^^^ associated types `Color` (from trait `Vehicle`), `Color` (from trait `Box`) must be specified
+ |
+ = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
+
+error[E0221]: ambiguous associated type `Color` in bounds of `C`
+ --> $DIR/associated-type-projection-from-multiple-supertraits.rs:28:29
+ |
+LL | type Color;
+ | ---------- ambiguous `Color` from `Vehicle`
+...
+LL | type Color;
+ | ---------- ambiguous `Color` from `Box`
+...
+LL | fn paint<C:BoxCar>(c: C, d: C::Color) {
+ | ^^^^^^^^ ambiguous associated type `Color`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn paint<C:BoxCar>(c: C, d: <C as Vehicle>::Color) {
+ | ~~~~~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | fn paint<C:BoxCar>(c: C, d: <C as Box>::Color) {
+ | ~~~~~~~~~~~~
+
+error[E0191]: the value of the associated types `Color` (from trait `Box`), `Color` (from trait `Vehicle`) must be specified
+ --> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:32
+ |
+LL | type Color;
+ | ---------- `Vehicle::Color` defined here
+...
+LL | type Color;
+ | ---------- `Box::Color` defined here
+...
+LL | fn dent_object_2<COLOR>(c: dyn BoxCar) where <dyn BoxCar as Vehicle>::Color = COLOR {
+ | ^^^^^^ associated types `Color` (from trait `Vehicle`), `Color` (from trait `Box`) must be specified
+ |
+ = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0191, E0221, E0222.
+For more information about an error, try `rustc --explain E0191`.
diff --git a/src/test/ui/associated-types/associated-type-projection-from-supertrait.rs b/src/test/ui/associated-types/associated-type-projection-from-supertrait.rs
new file mode 100644
index 000000000..7e05bcd30
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-projection-from-supertrait.rs
@@ -0,0 +1,36 @@
+// Test equality constraints in a where clause where the type being
+// equated appears in a supertrait.
+
+pub trait Vehicle {
+ type Color;
+
+ fn go(&self) { }
+}
+
+pub trait Car : Vehicle {
+ fn honk(&self) { }
+ fn chip_paint(&self, c: Self::Color) { }
+}
+
+struct Black;
+struct ModelT;
+impl Vehicle for ModelT { type Color = Black; }
+impl Car for ModelT { }
+
+struct Blue;
+struct ModelU;
+impl Vehicle for ModelU { type Color = Blue; }
+impl Car for ModelU { }
+
+fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
+fn a() { dent(ModelT, Black); }
+fn b() { dent(ModelT, Blue); } //~ ERROR mismatched types
+fn c() { dent(ModelU, Black); } //~ ERROR mismatched types
+fn d() { dent(ModelU, Blue); }
+
+fn e() { ModelT.chip_paint(Black); }
+fn f() { ModelT.chip_paint(Blue); } //~ ERROR mismatched types
+fn g() { ModelU.chip_paint(Black); } //~ ERROR mismatched types
+fn h() { ModelU.chip_paint(Blue); }
+
+pub fn main() { }
diff --git a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
new file mode 100644
index 000000000..b904ad102
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
@@ -0,0 +1,59 @@
+error[E0308]: mismatched types
+ --> $DIR/associated-type-projection-from-supertrait.rs:27:23
+ |
+LL | fn b() { dent(ModelT, Blue); }
+ | ---- ^^^^ expected struct `Black`, found struct `Blue`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/associated-type-projection-from-supertrait.rs:25:4
+ |
+LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
+ | ^^^^ ---- ---------------
+
+error[E0308]: mismatched types
+ --> $DIR/associated-type-projection-from-supertrait.rs:28:23
+ |
+LL | fn c() { dent(ModelU, Black); }
+ | ---- ^^^^^ expected struct `Blue`, found struct `Black`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/associated-type-projection-from-supertrait.rs:25:4
+ |
+LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
+ | ^^^^ ---- ---------------
+
+error[E0308]: mismatched types
+ --> $DIR/associated-type-projection-from-supertrait.rs:32:28
+ |
+LL | fn f() { ModelT.chip_paint(Blue); }
+ | ---------- ^^^^ expected struct `Black`, found struct `Blue`
+ | |
+ | arguments to this function are incorrect
+ |
+note: associated function defined here
+ --> $DIR/associated-type-projection-from-supertrait.rs:12:8
+ |
+LL | fn chip_paint(&self, c: Self::Color) { }
+ | ^^^^^^^^^^ ----- --------------
+
+error[E0308]: mismatched types
+ --> $DIR/associated-type-projection-from-supertrait.rs:33:28
+ |
+LL | fn g() { ModelU.chip_paint(Black); }
+ | ---------- ^^^^^ expected struct `Blue`, found struct `Black`
+ | |
+ | arguments to this function are incorrect
+ |
+note: associated function defined here
+ --> $DIR/associated-type-projection-from-supertrait.rs:12:8
+ |
+LL | fn chip_paint(&self, c: Self::Color) { }
+ | ^^^^^^^^^^ ----- --------------
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/associated-type-struct-construction.rs b/src/test/ui/associated-types/associated-type-struct-construction.rs
new file mode 100644
index 000000000..f8f8048fb
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-struct-construction.rs
@@ -0,0 +1,24 @@
+// Make sure that users can construct structs through associated types
+// in both expressions and patterns
+
+#![feature(more_qualified_paths)]
+
+// check-pass
+fn main() {
+ let <Foo as A>::Assoc { br } = <Foo as A>::Assoc { br: 2 };
+ assert!(br == 2);
+}
+
+struct StructStruct {
+ br: i8,
+}
+
+struct Foo;
+
+trait A {
+ type Assoc;
+}
+
+impl A for Foo {
+ type Assoc = StructStruct;
+}
diff --git a/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs b/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs
new file mode 100644
index 000000000..d5809ecd5
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-tuple-struct-construction.rs
@@ -0,0 +1,24 @@
+// Users cannot yet construct structs through associated types
+// in both expressions and patterns
+
+#![feature(more_qualified_paths)]
+
+fn main() {
+ let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+ //~^ ERROR expected method or associated constant, found associated type
+ //~| ERROR expected method or associated constant, found associated type
+ assert!(n == 2);
+}
+
+struct TupleStruct(i8);
+
+struct Foo;
+
+
+trait A {
+ type Assoc;
+}
+
+impl A for Foo {
+ type Assoc = TupleStruct;
+}
diff --git a/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr b/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr
new file mode 100644
index 000000000..bca7deeb5
--- /dev/null
+++ b/src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr
@@ -0,0 +1,19 @@
+error[E0575]: expected method or associated constant, found associated type `A::Assoc`
+ --> $DIR/associated-type-tuple-struct-construction.rs:7:32
+ |
+LL | let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: can't use a type alias as a constructor
+
+error[E0575]: expected method or associated constant, found associated type `A::Assoc`
+ --> $DIR/associated-type-tuple-struct-construction.rs:7:9
+ |
+LL | let <Foo as A>::Assoc(n) = <Foo as A>::Assoc(2);
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: can't use a type alias as a constructor
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0575`.
diff --git a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs
new file mode 100644
index 000000000..707bcac78
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs
@@ -0,0 +1,25 @@
+// Test that we do not ICE when the self type is `ty::err`, but rather
+// just propagate the error.
+
+#![crate_type = "lib"]
+#![feature(lang_items)]
+#![feature(no_core)]
+#![no_core]
+
+#[lang="sized"]
+pub trait Sized {
+ // Empty.
+}
+
+#[lang = "add"]
+trait Add<RHS=Self> {
+ type Output;
+
+ fn add(self, _: RHS) -> Self::Output;
+}
+
+fn ice<A>(a: A) {
+ let r = loop {};
+ r = r + a;
+ //~^ ERROR the trait bound `(): Add<A>` is not satisfied
+}
diff --git a/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr
new file mode 100644
index 000000000..8c3463a28
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `(): Add<A>` is not satisfied
+ --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11
+ |
+LL | r = r + a;
+ | ^ the trait `Add<A>` is not implemented for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-basic.rs b/src/test/ui/associated-types/associated-types-basic.rs
new file mode 100644
index 000000000..b7f6721ec
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-basic.rs
@@ -0,0 +1,14 @@
+// run-pass
+trait Foo {
+ type T;
+}
+
+impl Foo for i32 {
+ type T = isize;
+}
+
+fn main() {
+ let x: <i32 as Foo>::T = 22;
+ let y: isize = 44;
+ assert_eq!(x * 2, y);
+}
diff --git a/src/test/ui/associated-types/associated-types-binding-in-trait.rs b/src/test/ui/associated-types/associated-types-binding-in-trait.rs
new file mode 100644
index 000000000..2e42b3a2a
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-binding-in-trait.rs
@@ -0,0 +1,36 @@
+// run-pass
+// Test a case where the associated type binding (to `bool`, in this
+// case) is derived from the trait definition. Issue #21636.
+
+
+use std::vec;
+
+pub trait BitIter {
+ type Iter: Iterator<Item=bool>;
+ fn bit_iter(self) -> <Self as BitIter>::Iter;
+}
+
+impl BitIter for Vec<bool> {
+ type Iter = vec::IntoIter<bool>;
+ fn bit_iter(self) -> <Self as BitIter>::Iter {
+ self.into_iter()
+ }
+}
+
+fn count<T>(arg: T) -> usize
+ where T: BitIter
+{
+ let mut sum = 0;
+ for i in arg.bit_iter() {
+ if i {
+ sum += 1;
+ }
+ }
+ sum
+}
+
+fn main() {
+ let v = vec![true, false, true];
+ let c = count(v);
+ assert_eq!(c, 2);
+}
diff --git a/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs b/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs
new file mode 100644
index 000000000..c54bc3cd6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-binding-in-where-clause.rs
@@ -0,0 +1,38 @@
+// run-pass
+// Test equality constraints on associated types in a where clause.
+
+// pretty-expanded FIXME #23616
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+#[derive(PartialEq)]
+pub struct Bar;
+
+impl Foo for isize {
+ type A = usize;
+ fn boo(&self) -> usize { 42 }
+}
+
+impl Foo for char {
+ type A = Bar;
+ fn boo(&self) -> Bar { Bar }
+}
+
+fn foo_bar<I: Foo<A=Bar>>(x: I) -> Bar {
+ x.boo()
+}
+
+fn foo_uint<I: Foo<A=usize>>(x: I) -> usize {
+ x.boo()
+}
+
+pub fn main() {
+ let a = 42;
+ foo_uint(a);
+
+ let a = 'a';
+ foo_bar(a);
+}
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
new file mode 100644
index 000000000..6b2bbbe2e
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
@@ -0,0 +1,35 @@
+// Test equality constraints in a where clause where the type being
+// equated appears in a supertrait.
+
+pub trait Vehicle {
+ type Color;
+
+ fn go(&self) { }
+}
+
+pub trait Car : Vehicle {
+ fn honk(&self) { }
+}
+
+struct Black;
+struct ModelT;
+impl Vehicle for ModelT { type Color = Black; }
+impl Car for ModelT { }
+
+struct Blue;
+struct ModelU;
+impl Vehicle for ModelU { type Color = Blue; }
+impl Car for ModelU { }
+
+fn black_car<C:Car<Color=Black>>(c: C) {
+}
+
+fn blue_car<C:Car<Color=Blue>>(c: C) {
+}
+
+fn a() { black_car(ModelT); }
+fn b() { blue_car(ModelT); } //~ ERROR type mismatch
+fn c() { black_car(ModelU); } //~ ERROR type mismatch
+fn d() { blue_car(ModelU); }
+
+pub fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
new file mode 100644
index 000000000..0cccc6b38
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
@@ -0,0 +1,37 @@
+error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
+ |
+LL | fn b() { blue_car(ModelT); }
+ | ^^^^^^^^ type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
+ |
+note: expected this to be `Blue`
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:16:40
+ |
+LL | impl Vehicle for ModelT { type Color = Black; }
+ | ^^^^^
+note: required by a bound in `blue_car`
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:27:19
+ |
+LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
+ | ^^^^^^^^^^ required by this bound in `blue_car`
+
+error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
+ |
+LL | fn c() { black_car(ModelU); }
+ | ^^^^^^^^^ type mismatch resolving `<ModelU as Vehicle>::Color == Black`
+ |
+note: expected this to be `Black`
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:21:40
+ |
+LL | impl Vehicle for ModelU { type Color = Blue; }
+ | ^^^^
+note: required by a bound in `black_car`
+ --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:24:20
+ |
+LL | fn black_car<C:Car<Color=Black>>(c: C) {
+ | ^^^^^^^^^^^ required by this bound in `black_car`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-bound-ambiguity.rs b/src/test/ui/associated-types/associated-types-bound-ambiguity.rs
new file mode 100644
index 000000000..9f179b645
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-bound-ambiguity.rs
@@ -0,0 +1,23 @@
+// Make sure that if there are multiple applicable bounds on a projection, we
+// consider them ambiguous. In this test we are initially trying to solve
+// `Self::Repr: From<_>`, which is ambiguous until we later infer `_` to
+// `{integer}`.
+
+// check-pass
+
+trait PrimeField: Sized {
+ type Repr: From<u64> + From<Self>;
+ type Repr2: From<Self> + From<u64>;
+
+ fn method() {
+ Self::Repr::from(10);
+ Self::Repr2::from(10);
+ }
+}
+
+fn function<T: PrimeField>() {
+ T::Repr::from(10);
+ T::Repr2::from(10);
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-bound-failure.fixed b/src/test/ui/associated-types/associated-types-bound-failure.fixed
new file mode 100644
index 000000000..68ee38d16
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-bound-failure.fixed
@@ -0,0 +1,29 @@
+// run-rustfix
+// Test equality constraints on associated types in a where clause.
+#![allow(dead_code)]
+
+pub trait ToInt {
+ fn to_int(&self) -> isize;
+}
+
+pub trait GetToInt
+{
+ type R;
+
+ fn get(&self) -> <Self as GetToInt>::R;
+}
+
+fn foo<G>(g: G) -> isize
+ where G : GetToInt, <G as GetToInt>::R: ToInt
+{
+ ToInt::to_int(&g.get()) //~ ERROR E0277
+}
+
+fn bar<G : GetToInt>(g: G) -> isize
+ where G::R : ToInt
+{
+ ToInt::to_int(&g.get()) // OK
+}
+
+pub fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-bound-failure.rs b/src/test/ui/associated-types/associated-types-bound-failure.rs
new file mode 100644
index 000000000..31e073cc7
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-bound-failure.rs
@@ -0,0 +1,29 @@
+// run-rustfix
+// Test equality constraints on associated types in a where clause.
+#![allow(dead_code)]
+
+pub trait ToInt {
+ fn to_int(&self) -> isize;
+}
+
+pub trait GetToInt
+{
+ type R;
+
+ fn get(&self) -> <Self as GetToInt>::R;
+}
+
+fn foo<G>(g: G) -> isize
+ where G : GetToInt
+{
+ ToInt::to_int(&g.get()) //~ ERROR E0277
+}
+
+fn bar<G : GetToInt>(g: G) -> isize
+ where G::R : ToInt
+{
+ ToInt::to_int(&g.get()) // OK
+}
+
+pub fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-bound-failure.stderr b/src/test/ui/associated-types/associated-types-bound-failure.stderr
new file mode 100644
index 000000000..3eda22796
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-bound-failure.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the trait bound `<G as GetToInt>::R: ToInt` is not satisfied
+ --> $DIR/associated-types-bound-failure.rs:19:19
+ |
+LL | ToInt::to_int(&g.get())
+ | ------------- ^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
+ | |
+ | required by a bound introduced by this call
+ |
+help: consider further restricting the associated type
+ |
+LL | where G : GetToInt, <G as GetToInt>::R: ToInt
+ | +++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-bound.rs b/src/test/ui/associated-types/associated-types-bound.rs
new file mode 100644
index 000000000..0e9a229a5
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-bound.rs
@@ -0,0 +1,43 @@
+// run-pass
+// Test equality constrai32s on associated types in a where clause.
+
+
+pub trait ToI32 {
+ fn to_i32(&self) -> i32;
+}
+
+impl ToI32 for i32 {
+ fn to_i32(&self) -> i32 { *self }
+}
+
+impl ToI32 for u32 {
+ fn to_i32(&self) -> i32 { *self as i32 }
+}
+
+pub trait GetToI32
+{
+ type R : ToI32;
+
+ fn get(&self) -> <Self as GetToI32>::R;
+}
+
+impl GetToI32 for i32 {
+ type R = i32;
+ fn get(&self) -> i32 { *self }
+}
+
+impl GetToI32 for u32 {
+ type R = u32;
+ fn get(&self) -> u32 { *self }
+}
+
+fn foo<G>(g: G) -> i32
+ where G : GetToI32
+{
+ ToI32::to_i32(&g.get())
+}
+
+pub fn main() {
+ assert_eq!(foo(22i32), 22);
+ assert_eq!(foo(22u32), 22);
+}
diff --git a/src/test/ui/associated-types/associated-types-cc.rs b/src/test/ui/associated-types/associated-types-cc.rs
new file mode 100644
index 000000000..13f1d2720
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-cc.rs
@@ -0,0 +1,18 @@
+// run-pass
+#![allow(unused_variables)]
+// aux-build:associated-types-cc-lib.rs
+
+// Test that we are able to reference cross-crate traits that employ
+// associated types.
+
+extern crate associated_types_cc_lib as bar;
+
+use bar::Bar;
+
+fn foo<B:Bar>(b: B) -> <B as Bar>::T {
+ Bar::get(None::<B>)
+}
+
+fn main() {
+ println!("{}", foo(3));
+}
diff --git a/src/test/ui/associated-types/associated-types-coherence-failure.rs b/src/test/ui/associated-types/associated-types-coherence-failure.rs
new file mode 100644
index 000000000..c33f2ac96
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-coherence-failure.rs
@@ -0,0 +1,49 @@
+// 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>(PhantomData<(&'a (),B)>);
+
+/// Trait for moving into a `Cow`
+pub trait IntoCow<'a, B: ?Sized> {
+ /// Moves `self` into `Cow`
+ fn into_cow(self) -> Cow<'a, B>;
+}
+
+impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
+ fn into_cow(self) -> Cow<'a, B> {
+ Cow(PhantomData)
+ }
+}
+
+impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
+//~^ ERROR E0119
+ fn into_cow(self) -> Cow<'a, B> {
+ self
+ }
+}
+
+impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned {
+//~^ ERROR E0119
+ fn into_cow(self) -> Cow<'a, B> {
+ Cow(PhantomData)
+ }
+}
+
+impl ToOwned for u8 {
+ type Owned = &'static u8;
+ fn to_owned(&self) -> &'static u8 { panic!() }
+}
+
+/// A generalization of Clone to borrowed data.
+pub trait ToOwned {
+ type Owned;
+
+ /// Creates owned data from borrowed data, usually by copying.
+ fn to_owned(&self) -> Self::Owned;
+}
+
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-coherence-failure.stderr b/src/test/ui/associated-types/associated-types-coherence-failure.stderr
new file mode 100644
index 000000000..40c02dca3
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-coherence-failure.stderr
@@ -0,0 +1,21 @@
+error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `Cow<'_, _>`
+ --> $DIR/associated-types-coherence-failure.rs:21:1
+ |
+LL | impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
+ | ------------------------------------------------------------ first implementation here
+...
+LL | impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Cow<'_, _>`
+
+error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `&_`
+ --> $DIR/associated-types-coherence-failure.rs:28:1
+ |
+LL | impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
+ | ------------------------------------------------------------ first implementation here
+...
+LL | impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/associated-types/associated-types-conditional-dispatch.rs b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs
new file mode 100644
index 000000000..70ee60517
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-conditional-dispatch.rs
@@ -0,0 +1,66 @@
+// run-pass
+// Test that we evaluate projection predicates to winnow out
+// candidates during trait selection and method resolution (#20296).
+// If we don't properly winnow out candidates based on the output type
+// `Target=[A]`, then the impl marked with `(*)` is seen to conflict
+// with all the others.
+
+// pretty-expanded FIXME #23616
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+
+pub trait MyEq<U: ?Sized=Self> {
+ fn eq(&self, u: &U) -> bool;
+}
+
+impl<A, B> MyEq<[B]> for [A]
+ where A : MyEq<B>
+{
+ fn eq(&self, other: &[B]) -> bool {
+ self.len() == other.len() &&
+ self.iter().zip(other).all(|(a, b)| MyEq::eq(a, b))
+ }
+}
+
+// (*) This impl conflicts with everything unless the `Target=[A]`
+// constraint is considered.
+impl<'a, A, B, Lhs> MyEq<[B; 0]> for Lhs
+ where A: MyEq<B>, Lhs: Deref<Target=[A]>
+{
+ fn eq(&self, other: &[B; 0]) -> bool {
+ MyEq::eq(&**self, other)
+ }
+}
+
+struct DerefWithHelper<H, T> {
+ pub helper: H,
+ pub marker: PhantomData<T>,
+}
+
+trait Helper<T> {
+ fn helper_borrow(&self) -> &T;
+}
+
+impl<T> Helper<T> for Option<T> {
+ fn helper_borrow(&self) -> &T {
+ self.as_ref().unwrap()
+ }
+}
+
+impl<T, H: Helper<T>> Deref for DerefWithHelper<H, T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ self.helper.helper_borrow()
+ }
+}
+
+pub fn check<T: MyEq>(x: T, y: T) -> bool {
+ let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x),
+ marker: PhantomData };
+ d.eq(&y)
+}
+
+pub fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-constant-type.rs b/src/test/ui/associated-types/associated-types-constant-type.rs
new file mode 100644
index 000000000..1e4c113a5
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-constant-type.rs
@@ -0,0 +1,31 @@
+// run-pass
+
+trait SignedUnsigned {
+ type Opposite;
+ fn convert(self) -> Self::Opposite;
+}
+
+impl SignedUnsigned for isize {
+ type Opposite = usize;
+
+ fn convert(self) -> usize {
+ self as usize
+ }
+}
+
+impl SignedUnsigned for usize {
+ type Opposite = isize;
+
+ fn convert(self) -> isize {
+ self as isize
+ }
+}
+
+fn get(x: isize) -> <isize as SignedUnsigned>::Opposite {
+ x.convert()
+}
+
+fn main() {
+ let x = get(22);
+ assert_eq!(22, x);
+}
diff --git a/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs b/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs
new file mode 100644
index 000000000..05498ba63
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-doubleendediterator-object.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+fn pairwise_sub(mut t: Box<dyn DoubleEndedIterator<Item=isize>>) -> isize {
+ let mut result = 0;
+ loop {
+ let front = t.next();
+ let back = t.next_back();
+ match (front, back) {
+ (Some(f), Some(b)) => { result += b - f; }
+ _ => { return result; }
+ }
+ }
+}
+
+fn main() {
+ let v = vec![1, 2, 3, 4, 5, 6];
+ let r = pairwise_sub(Box::new(v.into_iter()));
+ assert_eq!(r, 9);
+}
diff --git a/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs
new file mode 100644
index 000000000..12ca10043
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![allow(dead_code)]
+// Check that we do not report ambiguities when equivalent predicates
+// (modulo bound lifetime names) appears in the environment
+// twice. Issue #21965.
+
+// pretty-expanded FIXME #23616
+
+fn foo<T>(t: T) -> i32
+ where T : for<'a> Fn(&'a u8) -> i32,
+ T : for<'b> Fn(&'b u8) -> i32,
+{
+ t(&3)
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs
new file mode 100644
index 000000000..9ffccd3d8
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(dead_code)]
+// Check that we do not report ambiguities when the same predicate
+// appears in the environment twice. Issue #21965.
+
+// pretty-expanded FIXME #23616
+
+trait Foo {
+ type B;
+
+ fn get() -> Self::B;
+}
+
+fn foo<T>() -> ()
+ where T : Foo<B=()>, T : Foo<B=()>
+{
+ <T as Foo>::get()
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-enum-field-named.rs b/src/test/ui/associated-types/associated-types-enum-field-named.rs
new file mode 100644
index 000000000..896d67213
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-enum-field-named.rs
@@ -0,0 +1,35 @@
+// run-pass
+// Test associated types appearing in struct-like enum variants.
+
+
+use self::VarValue::*;
+
+pub trait UnifyKey {
+ type Value;
+ fn to_index(&self) -> usize;
+}
+
+pub enum VarValue<K:UnifyKey> {
+ Redirect { to: K },
+ Root { value: K::Value, rank: usize },
+}
+
+fn get<'a,K:UnifyKey<Value=Option<V>>,V>(table: &'a Vec<VarValue<K>>, key: &K) -> &'a Option<V> {
+ match table[key.to_index()] {
+ VarValue::Redirect { to: ref k } => get(table, k),
+ VarValue::Root { value: ref v, rank: _ } => v,
+ }
+}
+
+impl UnifyKey for usize {
+ type Value = Option<char>;
+ fn to_index(&self) -> usize { *self }
+}
+
+fn main() {
+ let table = vec![/* 0 */ Redirect { to: 1 },
+ /* 1 */ Redirect { to: 3 },
+ /* 2 */ Root { value: Some('x'), rank: 0 },
+ /* 3 */ Redirect { to: 2 }];
+ assert_eq!(get(&table, &0), &Some('x'));
+}
diff --git a/src/test/ui/associated-types/associated-types-enum-field-numbered.rs b/src/test/ui/associated-types/associated-types-enum-field-numbered.rs
new file mode 100644
index 000000000..77ced3c07
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-enum-field-numbered.rs
@@ -0,0 +1,35 @@
+// run-pass
+// Test associated types appearing in tuple-like enum variants.
+
+
+use self::VarValue::*;
+
+pub trait UnifyKey {
+ type Value;
+ fn to_index(&self) -> usize;
+}
+
+pub enum VarValue<K:UnifyKey> {
+ Redirect(K),
+ Root(K::Value, usize),
+}
+
+fn get<'a,K:UnifyKey<Value=Option<V>>,V>(table: &'a Vec<VarValue<K>>, key: &K) -> &'a Option<V> {
+ match table[key.to_index()] {
+ VarValue::Redirect(ref k) => get(table, k),
+ VarValue::Root(ref v, _) => v,
+ }
+}
+
+impl UnifyKey for usize {
+ type Value = Option<char>;
+ fn to_index(&self) -> usize { *self }
+}
+
+fn main() {
+ let table = vec![/* 0 */ Redirect(1),
+ /* 1 */ Redirect(3),
+ /* 2 */ Root(Some('x'), 0),
+ /* 3 */ Redirect(2)];
+ assert_eq!(get(&table, &0), &Some('x'));
+}
diff --git a/src/test/ui/associated-types/associated-types-eq-1.rs b/src/test/ui/associated-types/associated-types-eq-1.rs
new file mode 100644
index 000000000..c371138ff
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-1.rs
@@ -0,0 +1,13 @@
+// Test equality constraints on associated types. Check that unsupported syntax
+// does not ICE.
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+fn foo2<I: Foo>(x: I) {
+ let _: A = x.boo(); //~ ERROR cannot find type `A` in this scope
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-eq-1.stderr b/src/test/ui/associated-types/associated-types-eq-1.stderr
new file mode 100644
index 000000000..e9ace7d25
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-1.stderr
@@ -0,0 +1,20 @@
+error[E0412]: cannot find type `A` in this scope
+ --> $DIR/associated-types-eq-1.rs:10:12
+ |
+LL | fn foo2<I: Foo>(x: I) {
+ | - similarly named type parameter `I` defined here
+LL | let _: A = x.boo();
+ | ^
+ |
+help: a type parameter with a similar name exists
+ |
+LL | let _: I = x.boo();
+ | ~
+help: you might be missing a type parameter
+ |
+LL | fn foo2<I: Foo, A>(x: I) {
+ | +++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/associated-types/associated-types-eq-2.rs b/src/test/ui/associated-types/associated-types-eq-2.rs
new file mode 100644
index 000000000..18e38d446
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-2.rs
@@ -0,0 +1,19 @@
+// Test equality constraints on associated types. Check we get an error when an
+// equality constraint is used in a qualified path.
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+struct Bar;
+
+impl Foo for isize {
+ type A = usize;
+ fn boo(&self) -> usize { 42 }
+}
+
+fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
+//~^ ERROR associated type bindings are not allowed here
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-eq-2.stderr b/src/test/ui/associated-types/associated-types-eq-2.stderr
new file mode 100644
index 000000000..23ee8cd23
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-2.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/associated-types-eq-2.rs:16:30
+ |
+LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
+ | ^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/associated-types/associated-types-eq-3.rs b/src/test/ui/associated-types/associated-types-eq-3.rs
new file mode 100644
index 000000000..f6988dcf6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-3.rs
@@ -0,0 +1,42 @@
+// Test equality constraints on associated types. Check we get type errors
+// where we should.
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+struct Bar;
+
+impl Foo for isize {
+ type A = usize;
+ fn boo(&self) -> usize {
+ 42
+ }
+}
+
+fn foo1<I: Foo<A=Bar>>(x: I) {
+ let _: Bar = x.boo();
+}
+
+fn foo2<I: Foo>(x: I) {
+ let _: Bar = x.boo();
+ //~^ ERROR mismatched types
+ //~| found associated type `<I as Foo>::A`
+ //~| expected struct `Bar`, found associated type
+ //~| expected struct `Bar`
+}
+
+
+pub fn baz(x: &dyn Foo<A=Bar>) {
+ let _: Bar = x.boo();
+}
+
+
+pub fn main() {
+ let a = 42;
+ foo1(a);
+ //~^ ERROR type mismatch resolving
+ baz(&a);
+ //~^ ERROR type mismatch resolving
+}
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
new file mode 100644
index 000000000..bed63a5e6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -0,0 +1,49 @@
+error[E0308]: mismatched types
+ --> $DIR/associated-types-eq-3.rs:23:18
+ |
+LL | let _: Bar = x.boo();
+ | --- ^^^^^^^ expected struct `Bar`, found associated type
+ | |
+ | expected due to this
+ |
+ = note: expected struct `Bar`
+ found associated type `<I as Foo>::A`
+help: consider constraining the associated type `<I as Foo>::A` to `Bar`
+ |
+LL | fn foo2<I: Foo<A = Bar>>(x: I) {
+ | +++++++++
+
+error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
+ --> $DIR/associated-types-eq-3.rs:38:5
+ |
+LL | foo1(a);
+ | ^^^^ type mismatch resolving `<isize as Foo>::A == Bar`
+ |
+note: expected this to be `Bar`
+ --> $DIR/associated-types-eq-3.rs:12:14
+ |
+LL | type A = usize;
+ | ^^^^^
+note: required by a bound in `foo1`
+ --> $DIR/associated-types-eq-3.rs:18:16
+ |
+LL | fn foo1<I: Foo<A=Bar>>(x: I) {
+ | ^^^^^ required by this bound in `foo1`
+
+error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
+ --> $DIR/associated-types-eq-3.rs:40:9
+ |
+LL | baz(&a);
+ | ^^ type mismatch resolving `<isize as Foo>::A == Bar`
+ |
+note: expected this to be `Bar`
+ --> $DIR/associated-types-eq-3.rs:12:14
+ |
+LL | type A = usize;
+ | ^^^^^
+ = note: required for the cast from `isize` to the object type `dyn Foo<A = Bar>`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0271, E0308.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-eq-expr-path.rs b/src/test/ui/associated-types/associated-types-eq-expr-path.rs
new file mode 100644
index 000000000..143992f29
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-expr-path.rs
@@ -0,0 +1,16 @@
+// Check that an associated type cannot be bound in an expression path.
+
+trait Foo {
+ type A;
+ fn bar() -> isize;
+}
+
+impl Foo for isize {
+ type A = usize;
+ fn bar() -> isize { 42 }
+}
+
+pub fn main() {
+ let x: isize = Foo::<A=usize>::bar();
+ //~^ ERROR associated type bindings are not allowed here
+}
diff --git a/src/test/ui/associated-types/associated-types-eq-expr-path.stderr b/src/test/ui/associated-types/associated-types-eq-expr-path.stderr
new file mode 100644
index 000000000..bd354cf3e
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-expr-path.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/associated-types-eq-expr-path.rs:14:26
+ |
+LL | let x: isize = Foo::<A=usize>::bar();
+ | ^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.rs b/src/test/ui/associated-types/associated-types-eq-hr.rs
new file mode 100644
index 000000000..dc653f7f2
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-hr.rs
@@ -0,0 +1,111 @@
+// Check testing of equality constraints in a higher-ranked context.
+
+pub trait TheTrait<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+struct IntStruct {
+ x: isize,
+}
+
+impl<'a> TheTrait<&'a isize> for IntStruct {
+ type A = &'a isize;
+
+ fn get(&self, t: &'a isize) -> &'a isize {
+ t
+ }
+}
+
+struct UintStruct {
+ x: isize,
+}
+
+impl<'a> TheTrait<&'a isize> for UintStruct {
+ type A = &'a usize;
+
+ fn get(&self, t: &'a isize) -> &'a usize {
+ panic!()
+ }
+}
+
+struct Tuple {}
+
+impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
+ type A = &'a isize;
+
+ fn get(&self, t: (&'a isize, &'a isize)) -> &'a isize {
+ t.0
+ }
+}
+
+fn foo<T>()
+where
+ T: for<'x> TheTrait<&'x isize, A = &'x isize>,
+{
+ // ok for IntStruct, but not UintStruct
+}
+
+fn bar<T>()
+where
+ T: for<'x> TheTrait<&'x isize, A = &'x usize>,
+{
+ // ok for UintStruct, but not IntStruct
+}
+
+fn tuple_one<T>()
+where
+ T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
+{
+ // not ok for tuple, two lifetimes and we pick first
+}
+
+fn tuple_two<T>()
+where
+ T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
+{
+ // not ok for tuple, two lifetimes and we pick second
+}
+
+fn tuple_three<T>()
+where
+ T: for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>,
+{
+ // ok for tuple
+}
+
+fn tuple_four<T>()
+where
+ T: for<'x, 'y> TheTrait<(&'x isize, &'y isize)>,
+{
+ // not ok for tuple, two lifetimes, and lifetime matching is invariant
+}
+
+pub fn call_foo() {
+ foo::<IntStruct>();
+ foo::<UintStruct>(); //~ ERROR type mismatch
+}
+
+pub fn call_bar() {
+ bar::<IntStruct>(); //~ ERROR type mismatch
+ bar::<UintStruct>();
+}
+
+pub fn call_tuple_one() {
+ tuple_one::<Tuple>();
+}
+
+pub fn call_tuple_two() {
+ tuple_two::<Tuple>();
+}
+
+pub fn call_tuple_three() {
+ tuple_three::<Tuple>();
+}
+
+pub fn call_tuple_four() {
+ tuple_four::<Tuple>();
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr
new file mode 100644
index 000000000..b306ae273
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -0,0 +1,47 @@
+error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
+ --> $DIR/associated-types-eq-hr.rs:87:5
+ |
+LL | foo::<UintStruct>();
+ | ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
+ |
+note: expected this to be `&isize`
+ --> $DIR/associated-types-eq-hr.rs:26:14
+ |
+LL | type A = &'a usize;
+ | ^^^^^^^^^
+ = note: expected reference `&isize`
+ found reference `&usize`
+note: required by a bound in `foo`
+ --> $DIR/associated-types-eq-hr.rs:45:36
+ |
+LL | fn foo<T>()
+ | --- required by a bound in this
+LL | where
+LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
+ | ^^^^^^^^^^^^^ required by this bound in `foo`
+
+error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
+ --> $DIR/associated-types-eq-hr.rs:91:5
+ |
+LL | bar::<IntStruct>();
+ | ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
+ |
+note: expected this to be `&usize`
+ --> $DIR/associated-types-eq-hr.rs:14:14
+ |
+LL | type A = &'a isize;
+ | ^^^^^^^^^
+ = note: expected reference `&usize`
+ found reference `&isize`
+note: required by a bound in `bar`
+ --> $DIR/associated-types-eq-hr.rs:52:36
+ |
+LL | fn bar<T>()
+ | --- required by a bound in this
+LL | where
+LL | T: for<'x> TheTrait<&'x isize, A = &'x usize>,
+ | ^^^^^^^^^^^^^ required by this bound in `bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-eq-obj.rs b/src/test/ui/associated-types/associated-types-eq-obj.rs
new file mode 100644
index 000000000..c202c376c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-eq-obj.rs
@@ -0,0 +1,25 @@
+// run-pass
+// Test equality constraints on associated types inside of an object type
+
+// pretty-expanded FIXME #23616
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+pub struct Bar;
+
+impl Foo for char {
+ type A = Bar;
+ fn boo(&self) -> Bar { Bar }
+}
+
+fn baz(x: &dyn Foo<A=Bar>) -> Bar {
+ x.boo()
+}
+
+pub fn main() {
+ let a = 'a';
+ baz(&a);
+}
diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed b/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed
new file mode 100644
index 000000000..80bbef174
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused_variables)]
+
+trait Get {
+ type Value;
+ fn get(&self) -> <Self as Get>::Value;
+}
+
+trait Other {
+ fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+ //~^ ERROR the trait bound `Self: Get` is not satisfied
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.rs b/src/test/ui/associated-types/associated-types-for-unimpl-trait.rs
new file mode 100644
index 000000000..0f6cea8e6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(unused_variables)]
+
+trait Get {
+ type Value;
+ fn get(&self) -> <Self as Get>::Value;
+}
+
+trait Other {
+ fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+ //~^ ERROR the trait bound `Self: Get` is not satisfied
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
new file mode 100644
index 000000000..6552c8be7
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `Self: Get` is not satisfied
+ --> $DIR/associated-types-for-unimpl-trait.rs:10:40
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ |
+help: consider further restricting `Self`
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+ | +++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-from-supertrait.rs b/src/test/ui/associated-types/associated-types-from-supertrait.rs
new file mode 100644
index 000000000..8f40b94c0
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-from-supertrait.rs
@@ -0,0 +1,8 @@
+// run-pass
+
+trait Foo: Iterator<Item = i32> {}
+trait Bar: Foo {}
+
+fn main() {
+ let _: &dyn Bar;
+}
diff --git a/src/test/ui/associated-types/associated-types-impl-redirect.rs b/src/test/ui/associated-types/associated-types-impl-redirect.rs
new file mode 100644
index 000000000..8fa20cdf4
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-impl-redirect.rs
@@ -0,0 +1,51 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_mut)]
+#![allow(unused_imports)]
+// Test how resolving a projection interacts with inference. In this
+// case, we were eagerly unifying the type variable for the iterator
+// type with `I` from the where clause, ignoring the in-scope `impl`
+// for `ByRef`. The right answer was to consider the result ambiguous
+// until more type information was available.
+
+#![feature(lang_items)]
+#![no_implicit_prelude]
+
+use std::marker::Sized;
+use std::option::Option::{None, Some, self};
+
+trait Iterator {
+ type Item;
+
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+trait IteratorExt: Iterator + Sized {
+ fn by_ref(&mut self) -> ByRef<Self> {
+ ByRef(self)
+ }
+}
+
+impl<I> IteratorExt for I where I: Iterator {}
+
+struct ByRef<'a, I: 'a + Iterator>(&'a mut I);
+
+impl<'a, I: Iterator> Iterator for ByRef<'a, I> {
+ type Item = I::Item;
+
+ fn next(&mut self) -> Option< <I as Iterator>::Item > {
+ self.0.next()
+ }
+}
+
+fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
+
+fn test<A, I: Iterator<Item=A>>(mut it: I) {
+ is_iterator_of::<A, _>(&it.by_ref());
+}
+
+fn test2<A, I1: Iterator<Item=A>, I2: Iterator<Item=I1::Item>>(mut it: I2) {
+ is_iterator_of::<A, _>(&it)
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-in-ambiguous-context.rs b/src/test/ui/associated-types/associated-types-in-ambiguous-context.rs
new file mode 100644
index 000000000..51b53908f
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-ambiguous-context.rs
@@ -0,0 +1,29 @@
+trait Get {
+ type Value;
+ fn get(&self) -> <Self as Get>::Value;
+}
+
+fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
+//~^ ERROR ambiguous associated type
+
+trait Grab {
+ type Value;
+ fn grab(&self) -> Grab::Value;
+ //~^ ERROR ambiguous associated type
+
+ fn get(&self) -> Get::Value;
+ //~^ ERROR ambiguous associated type
+}
+
+trait Bar {}
+
+trait Foo where Foo::Assoc: Bar {
+//~^ ERROR ambiguous associated type
+ type Assoc;
+}
+
+type X = std::ops::Deref::Target;
+//~^ ERROR ambiguous associated type
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-in-ambiguous-context.stderr b/src/test/ui/associated-types/associated-types-in-ambiguous-context.stderr
new file mode 100644
index 000000000..289911779
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-ambiguous-context.stderr
@@ -0,0 +1,33 @@
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:6:36
+ |
+LL | fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
+ | ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:20:17
+ |
+LL | trait Foo where Foo::Assoc: Bar {
+ | ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:25:10
+ |
+LL | type X = std::ops::Deref::Target;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Deref>::Target`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:11:23
+ |
+LL | fn grab(&self) -> Grab::Value;
+ | ^^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Grab>::Value`
+
+error[E0223]: ambiguous associated type
+ --> $DIR/associated-types-in-ambiguous-context.rs:14:22
+ |
+LL | fn get(&self) -> Get::Value;
+ | ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs b/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs
new file mode 100644
index 000000000..88bb5fe0a
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-bound-type-arg.rs
@@ -0,0 +1,17 @@
+// run-pass
+// Test the case where we resolve `C::Result` and the trait bound
+// itself includes a `Self::Item` shorthand.
+//
+// Regression test for issue #33425.
+
+trait ParallelIterator {
+ type Item;
+ fn drive_unindexed<C>(self, consumer: C) -> C::Result
+ where C: Consumer<Self::Item>;
+}
+
+pub trait Consumer<ITEM> {
+ type Result;
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-in-default-method.rs b/src/test/ui/associated-types/associated-types-in-default-method.rs
new file mode 100644
index 000000000..80ffbf585
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-default-method.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+trait Get {
+ type Value;
+ fn get(&self) -> &<Self as Get>::Value;
+ fn grab(&self) -> &<Self as Get>::Value {
+ self.get()
+ }
+}
+
+struct Struct {
+ x: isize,
+}
+
+impl Get for Struct {
+ type Value = isize;
+ fn get(&self) -> &isize {
+ &self.x
+ }
+}
+
+fn main() {
+ let s = Struct {
+ x: 100,
+ };
+ assert_eq!(*s.grab(), 100);
+}
diff --git a/src/test/ui/associated-types/associated-types-in-fn.rs b/src/test/ui/associated-types/associated-types-in-fn.rs
new file mode 100644
index 000000000..9c588a528
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-fn.rs
@@ -0,0 +1,28 @@
+// run-pass
+
+trait Get {
+ type Value;
+ fn get(&self) -> &<Self as Get>::Value;
+}
+
+struct Struct {
+ x: isize,
+}
+
+impl Get for Struct {
+ type Value = isize;
+ fn get(&self) -> &isize {
+ &self.x
+ }
+}
+
+fn grab<T:Get>(x: &T) -> &<T as Get>::Value {
+ x.get()
+}
+
+fn main() {
+ let s = Struct {
+ x: 100,
+ };
+ assert_eq!(*grab(&s), 100);
+}
diff --git a/src/test/ui/associated-types/associated-types-in-impl-generics.rs b/src/test/ui/associated-types/associated-types-in-impl-generics.rs
new file mode 100644
index 000000000..0ddd99cbf
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-impl-generics.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+trait Get {
+ type Value;
+ fn get(&self) -> &<Self as Get>::Value;
+}
+
+struct Struct {
+ x: isize,
+}
+
+impl Get for Struct {
+ type Value = isize;
+ fn get(&self) -> &isize {
+ &self.x
+ }
+}
+
+trait Grab {
+ type U;
+ fn grab(&self) -> &<Self as Grab>::U;
+}
+
+impl<T:Get> Grab for T {
+ type U = <T as Get>::Value;
+ fn grab(&self) -> &<T as Get>::Value {
+ self.get()
+ }
+}
+
+fn main() {
+ let s = Struct {
+ x: 100,
+ };
+ assert_eq!(*s.grab(), 100);
+}
diff --git a/src/test/ui/associated-types/associated-types-in-inherent-method.rs b/src/test/ui/associated-types/associated-types-in-inherent-method.rs
new file mode 100644
index 000000000..1f29e9668
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-in-inherent-method.rs
@@ -0,0 +1,30 @@
+// run-pass
+
+trait Get {
+ type Value;
+ fn get(&self) -> &<Self as Get>::Value;
+}
+
+struct Struct {
+ x: isize,
+}
+
+impl Get for Struct {
+ type Value = isize;
+ fn get(&self) -> &isize {
+ &self.x
+ }
+}
+
+impl Struct {
+ fn grab<T:Get>(x: &T) -> &<T as Get>::Value {
+ x.get()
+ }
+}
+
+fn main() {
+ let s = Struct {
+ x: 100,
+ };
+ assert_eq!(*Struct::grab(&s), 100);
+}
diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.rs b/src/test/ui/associated-types/associated-types-incomplete-object.rs
new file mode 100644
index 000000000..4627dfd2b
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-incomplete-object.rs
@@ -0,0 +1,31 @@
+// Check that the user gets an error if they omit a binding from an
+// object type.
+
+pub trait Foo {
+ type A;
+ type B;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+struct Bar;
+
+impl Foo for isize {
+ type A = usize;
+ type B = char;
+ fn boo(&self) -> usize {
+ 42
+ }
+}
+
+pub fn main() {
+ let a = &42isize as &dyn Foo<A=usize, B=char>;
+
+ let b = &42isize as &dyn Foo<A=usize>;
+ //~^ ERROR the value of the associated type `B` (from trait `Foo`) must be specified
+
+ let c = &42isize as &dyn Foo<B=char>;
+ //~^ ERROR the value of the associated type `A` (from trait `Foo`) must be specified
+
+ let d = &42isize as &dyn Foo;
+ //~^ ERROR the value of the associated types `A` (from trait `Foo`), `B` (from trait
+}
diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr
new file mode 100644
index 000000000..32866c714
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr
@@ -0,0 +1,32 @@
+error[E0191]: the value of the associated type `B` (from trait `Foo`) must be specified
+ --> $DIR/associated-types-incomplete-object.rs:23:30
+ |
+LL | type B;
+ | ------ `B` defined here
+...
+LL | let b = &42isize as &dyn Foo<A=usize>;
+ | ^^^^^^^^^^^^ help: specify the associated type: `Foo<A=usize, B = Type>`
+
+error[E0191]: the value of the associated type `A` (from trait `Foo`) must be specified
+ --> $DIR/associated-types-incomplete-object.rs:26:30
+ |
+LL | type A;
+ | ------ `A` defined here
+...
+LL | let c = &42isize as &dyn Foo<B=char>;
+ | ^^^^^^^^^^^ help: specify the associated type: `Foo<B=char, A = Type>`
+
+error[E0191]: the value of the associated types `A` (from trait `Foo`), `B` (from trait `Foo`) must be specified
+ --> $DIR/associated-types-incomplete-object.rs:29:30
+ |
+LL | type A;
+ | ------ `A` defined here
+LL | type B;
+ | ------ `B` defined here
+...
+LL | let d = &42isize as &dyn Foo;
+ | ^^^ help: specify the associated types: `Foo<A = Type, B = Type>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0191`.
diff --git a/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs b/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs
new file mode 100644
index 000000000..3bd3f3a75
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs
@@ -0,0 +1,14 @@
+// Test that we report an error if the trait ref in a qualified type
+// uses invalid type arguments.
+
+trait Foo<T> {
+ type Bar;
+ fn get_bar(&self) -> Self::Bar;
+}
+
+fn f<T:Foo<isize>>(t: &T) {
+ let u: <T as Foo<usize>>::Bar = t.get_bar();
+ //~^ ERROR the trait bound `T: Foo<usize>` is not satisfied
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr b/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr
new file mode 100644
index 000000000..8fecfdf7b
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: Foo<usize>` is not satisfied
+ --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12
+ |
+LL | let u: <T as Foo<usize>>::Bar = t.get_bar();
+ | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `T`
+ |
+help: consider further restricting this bound
+ |
+LL | fn f<T:Foo<isize> + Foo<usize>>(t: &T) {
+ | ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-issue-17359.rs b/src/test/ui/associated-types/associated-types-issue-17359.rs
new file mode 100644
index 000000000..88a8a6490
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-17359.rs
@@ -0,0 +1,10 @@
+// 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 {
+ type Type;
+}
+
+impl Trait for isize {} //~ ERROR missing: `Type`
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-issue-17359.stderr b/src/test/ui/associated-types/associated-types-issue-17359.stderr
new file mode 100644
index 000000000..9e40d8095
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-17359.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `Type`
+ --> $DIR/associated-types-issue-17359.rs:8:1
+ |
+LL | type Type;
+ | --------- `Type` from trait
+...
+LL | impl Trait for isize {}
+ | ^^^^^^^^^^^^^^^^^^^^ missing `Type` in implementation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/associated-types/associated-types-issue-20220.rs b/src/test/ui/associated-types/associated-types-issue-20220.rs
new file mode 100644
index 000000000..19fa7a608
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-20220.rs
@@ -0,0 +1,28 @@
+// run-pass
+// Test references to `Self::Item` in the trait. Issue #20220.
+
+
+use std::vec;
+
+trait IntoIteratorX {
+ type Item;
+ type IntoIter: Iterator<Item=Self::Item>;
+
+ fn into_iter_x(self) -> Self::IntoIter;
+}
+
+impl<T> IntoIteratorX for Vec<T> {
+ type Item = T;
+ type IntoIter = vec::IntoIter<T>;
+
+ fn into_iter_x(self) -> vec::IntoIter<T> {
+ self.into_iter()
+ }
+}
+
+fn main() {
+ let vec = vec![1, 2, 3];
+ for (i, e) in vec.into_iter().enumerate() {
+ assert_eq!(i+1, e);
+ }
+}
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.rs b/src/test/ui/associated-types/associated-types-issue-20346.rs
new file mode 100644
index 000000000..0cce847e1
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-20346.rs
@@ -0,0 +1,35 @@
+// Test that we reliably check the value of the associated type.
+
+#![crate_type = "lib"]
+#![no_implicit_prelude]
+
+use std::option::Option::{self, None, Some};
+use std::vec::Vec;
+
+trait Iterator {
+ type Item;
+
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
+
+struct Adapter<I> {
+ iter: I,
+ found_none: bool,
+}
+
+impl<T, I> Iterator for Adapter<I> where I: Iterator<Item=Option<T>> {
+ type Item = T;
+
+ fn next(&mut self) -> Option<T> {
+ loop {}
+ }
+}
+
+fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
+ is_iterator_of::<Option<T>, _>(&it); // Sanity check
+ let adapter = Adapter { iter: it, found_none: false };
+ is_iterator_of::<T, _>(&adapter); // OK
+ is_iterator_of::<Option<T>, _>(&adapter); //~ ERROR type mismatch
+}
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
new file mode 100644
index 000000000..a67cf9928
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -0,0 +1,25 @@
+error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+ --> $DIR/associated-types-issue-20346.rs:34:5
+ |
+LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
+ | - this type parameter
+...
+LL | is_iterator_of::<Option<T>, _>(&adapter);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
+ |
+note: expected this to be `Option<T>`
+ --> $DIR/associated-types-issue-20346.rs:23:17
+ |
+LL | type Item = T;
+ | ^
+ = note: expected enum `Option<T>`
+ found type parameter `T`
+note: required by a bound in `is_iterator_of`
+ --> $DIR/associated-types-issue-20346.rs:15:34
+ |
+LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
+ | ^^^^^^ required by this bound in `is_iterator_of`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-issue-20371.rs b/src/test/ui/associated-types/associated-types-issue-20371.rs
new file mode 100644
index 000000000..ae8a8767d
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-20371.rs
@@ -0,0 +1,9 @@
+// run-pass
+// Test that we are able to have an impl that defines an associated type
+// before the actual trait.
+
+// pretty-expanded FIXME #23616
+
+impl X for f64 { type Y = isize; }
+trait X { type Y; }
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-issue-21212.rs b/src/test/ui/associated-types/associated-types-issue-21212.rs
new file mode 100644
index 000000000..ce27eac4d
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-issue-21212.rs
@@ -0,0 +1,22 @@
+// run-pass
+#![allow(unused_variables)]
+// Regression test for #21212: an overflow occurred during trait
+// checking where normalizing `Self::Input` led to normalizing the
+// where clauses in the environment which in turn required normalizing
+// `Self::Input`.
+
+
+pub trait Parser {
+ type Input;
+
+ fn parse(input: <Self as Parser>::Input) {
+ panic!()
+ }
+}
+
+impl <P> Parser for P {
+ type Input = ();
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-iterator-binding.rs b/src/test/ui/associated-types/associated-types-iterator-binding.rs
new file mode 100644
index 000000000..7c5528c98
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-iterator-binding.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+fn pairwise_sub<T:DoubleEndedIterator<Item=isize>>(mut t: T) -> isize {
+ let mut result = 0;
+ loop {
+ let front = t.next();
+ let back = t.next_back();
+ match (front, back) {
+ (Some(f), Some(b)) => { result += b - f; }
+ _ => { return result; }
+ }
+ }
+}
+
+fn main() {
+ let v = vec![1, 2, 3, 4, 5, 6];
+ let r = pairwise_sub(v.into_iter());
+ assert_eq!(r, 9);
+}
diff --git a/src/test/ui/associated-types/associated-types-method.rs b/src/test/ui/associated-types/associated-types-method.rs
new file mode 100644
index 000000000..45df3ac20
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-method.rs
@@ -0,0 +1,28 @@
+// run-pass
+// Test that methods whose impl-trait-ref contains associated types
+// are supported.
+
+trait Device {
+ type Resources;
+}
+#[allow(unused_tuple_struct_fields)]
+struct Foo<D, R>(D, R);
+
+trait Tr {
+ fn present(&self) {}
+}
+
+impl<D: Device> Tr for Foo<D, D::Resources> {
+ fn present(&self) {}
+}
+
+struct Res;
+struct Dev;
+impl Device for Dev {
+ type Resources = Res;
+}
+
+fn main() {
+ let foo = Foo(Dev, Res);
+ foo.present();
+}
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.rs b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.rs
new file mode 100644
index 000000000..daeaf9011
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.rs
@@ -0,0 +1,46 @@
+trait Foo {
+ type X;
+ type Y;
+}
+
+fn have_x_want_x<T:Foo<X=u32>>(t: &T)
+{
+ want_x(t);
+}
+
+fn have_x_want_y<T:Foo<X=u32>>(t: &T)
+{
+ want_y(t); //~ ERROR type mismatch
+}
+
+fn have_y_want_x<T:Foo<Y=i32>>(t: &T)
+{
+ want_x(t); //~ ERROR type mismatch
+}
+
+fn have_y_want_y<T:Foo<Y=i32>>(t: &T)
+{
+ want_y(t);
+}
+
+fn have_xy_want_x<T:Foo<X=u32,Y=i32>>(t: &T)
+{
+ want_x(t);
+}
+
+fn have_xy_want_y<T:Foo<X=u32,Y=i32>>(t: &T)
+{
+ want_y(t);
+}
+
+fn have_xy_want_xy<T:Foo<X=u32,Y=i32>>(t: &T)
+{
+ want_x(t);
+ want_y(t);
+}
+
+fn want_x<T:Foo<X=u32>>(t: &T) { }
+
+fn want_y<T:Foo<Y=i32>>(t: &T) { }
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
new file mode 100644
index 000000000..922cf88a0
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
@@ -0,0 +1,39 @@
+error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
+ --> $DIR/associated-types-multiple-types-one-trait.rs:13:5
+ |
+LL | want_y(t);
+ | ^^^^^^ expected `i32`, found associated type
+ |
+ = note: expected type `i32`
+ found associated type `<T as Foo>::Y`
+note: required by a bound in `want_y`
+ --> $DIR/associated-types-multiple-types-one-trait.rs:44:17
+ |
+LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
+ | ^^^^^ required by this bound in `want_y`
+help: consider constraining the associated type `<T as Foo>::Y` to `i32`
+ |
+LL | fn have_x_want_y<T:Foo<X=u32, Y = i32>>(t: &T)
+ | +++++++++
+
+error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
+ --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
+ |
+LL | want_x(t);
+ | ^^^^^^ expected `u32`, found associated type
+ |
+ = note: expected type `u32`
+ found associated type `<T as Foo>::X`
+note: required by a bound in `want_x`
+ --> $DIR/associated-types-multiple-types-one-trait.rs:42:17
+ |
+LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
+ | ^^^^^ required by this bound in `want_x`
+help: consider constraining the associated type `<T as Foo>::X` to `u32`
+ |
+LL | fn have_y_want_x<T:Foo<Y=i32, X = u32>>(t: &T)
+ | +++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-nested-projections.rs b/src/test/ui/associated-types/associated-types-nested-projections.rs
new file mode 100644
index 000000000..76ba74962
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-nested-projections.rs
@@ -0,0 +1,44 @@
+// run-pass
+#![allow(unused_variables)]
+// Test that we can resolve nested projection types. Issue #20666.
+
+// pretty-expanded FIXME #23616
+
+use std::slice;
+
+trait Bound {}
+
+impl<'a> Bound for &'a i32 {}
+
+trait IntoIterator {
+ type Iter: Iterator;
+
+ fn into_iter(self) -> Self::Iter;
+}
+
+impl<'a, T> IntoIterator for &'a [T; 3] {
+ type Iter = slice::Iter<'a, T>;
+
+ fn into_iter(self) -> slice::Iter<'a, T> {
+ self.iter()
+ }
+}
+
+fn foo<X>(x: X) where
+ X: IntoIterator,
+ <<X as IntoIterator>::Iter as Iterator>::Item: Bound,
+{
+}
+
+fn bar<T, I, X>(x: X) where
+ T: Bound,
+ I: Iterator<Item=T>,
+ X: IntoIterator<Iter=I>,
+{
+
+}
+
+fn main() {
+ foo(&[0, 1, 2]);
+ bar(&[0, 1, 2]);
+}
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.rs b/src/test/ui/associated-types/associated-types-no-suitable-bound.rs
new file mode 100644
index 000000000..d42460a4c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.rs
@@ -0,0 +1,16 @@
+trait Get {
+ type Value;
+ fn get(&self) -> <Self as Get>::Value;
+}
+
+struct Struct {
+ x: isize,
+}
+
+impl Struct {
+ fn uhoh<T>(foo: <T as Get>::Value) {}
+ //~^ ERROR the trait bound `T: Get` is not satisfied
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
new file mode 100644
index 000000000..b2ee1b5e6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `T: Get` is not satisfied
+ --> $DIR/associated-types-no-suitable-bound.rs:11:21
+ |
+LL | fn uhoh<T>(foo: <T as Get>::Value) {}
+ | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | fn uhoh<T: Get>(foo: <T as Get>::Value) {}
+ | +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.rs b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.rs
new file mode 100644
index 000000000..17dfa1773
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.rs
@@ -0,0 +1,21 @@
+// 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`.
+//
+// See also associated-types-no-suitable-supertrait.rs, which checks
+// that we see the same error when making this mistake on an impl
+// rather than the default method impl.
+//
+// See also run-pass/associated-types-projection-to-unrelated-trait.rs,
+// which checks that the trait interface itself is not considered an
+// error as long as all impls satisfy the constraint.
+
+trait Get {
+ type Value;
+}
+
+trait Other {
+ fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+ //~^ ERROR the trait bound `Self: Get` is not satisfied
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
new file mode 100644
index 000000000..2e40dbd06
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `Self: Get` is not satisfied
+ --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ |
+help: consider further restricting `Self`
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+ | +++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.rs b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.rs
new file mode 100644
index 000000000..c373c5855
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.rs
@@ -0,0 +1,26 @@
+// 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`.
+//
+// See also associated-types-no-suitable-supertrait-2.rs, which checks
+// that we see the same error if we get around to checking the default
+// method body.
+//
+// See also run-pass/associated-types-projection-to-unrelated-trait.rs,
+// which checks that the trait interface itself is not considered an
+// error as long as all impls satisfy the constraint.
+
+trait Get {
+ type Value;
+}
+
+trait Other {
+ fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+ //~^ ERROR the trait bound `Self: Get` is not satisfied
+}
+
+impl<T:Get> Other for T {
+ fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
+ //~^ ERROR the trait bound `(T, U): Get` is not satisfied
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
new file mode 100644
index 000000000..bd3ee2abd
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr
@@ -0,0 +1,20 @@
+error[E0277]: the trait bound `(T, U): Get` is not satisfied
+ --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
+
+error[E0277]: the trait bound `Self: Get` is not satisfied
+ --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ |
+help: consider further restricting `Self`
+ |
+LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get {}
+ | +++++++++++++++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs
new file mode 100644
index 000000000..7c54efb83
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs
@@ -0,0 +1,38 @@
+// run-pass
+#![allow(unused_variables)]
+// Test that we normalize associated types that appear in a bound that
+// contains a binding. Issue #21664.
+
+// pretty-expanded FIXME #23616
+
+#![allow(dead_code)]
+
+pub trait Integral {
+ type Opposite;
+}
+
+impl Integral for i32 {
+ type Opposite = u32;
+}
+
+impl Integral for u32 {
+ type Opposite = i32;
+}
+
+pub trait FnLike<A> {
+ type R;
+
+ fn dummy(&self, a: A) -> Self::R { loop { } }
+}
+
+fn foo<T>()
+ where T : FnLike<<i32 as Integral>::Opposite, R=bool>
+{
+ bar::<T>();
+}
+
+fn bar<T>()
+ where T : FnLike<u32, R=bool>
+{}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
new file mode 100644
index 000000000..e09aa3663
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
@@ -0,0 +1,35 @@
+// run-pass
+#![allow(unused_variables)]
+// Test that we normalize associated types that appear in bounds; if
+// we didn't, the call to `self.split2()` fails to type check.
+
+// pretty-expanded FIXME #23616
+
+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: u32, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+ where P: FnMut(&Self::Item) -> bool;
+}
+
+impl<T> SliceExt2 for [T] {
+ type Item = T;
+
+ fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
+ loop {}
+ }
+
+ fn splitn2<P>(&self, n: u32, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+ SliceExt2::split2(self, pred);
+ loop {}
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs b/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs
new file mode 100644
index 000000000..dcfae0f37
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-normalize-in-bounds.rs
@@ -0,0 +1,35 @@
+// run-pass
+#![allow(unused_variables)]
+// Test that we normalize associated types that appear in bounds; if
+// we didn't, the call to `self.split2()` fails to type check.
+
+// pretty-expanded FIXME #23616
+
+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: usize, pred: P) -> SplitsN<Splits<'a, Self::Item, P>>
+ where P: FnMut(&Self::Item) -> bool;
+}
+
+impl<T> SliceExt2 for [T] {
+ type Item = T;
+
+ fn split2<P>(&self, pred: P) -> Splits<T, P> where P: FnMut(&T) -> bool {
+ loop {}
+ }
+
+ fn splitn2<P>(&self, n: usize, pred: P) -> SplitsN<Splits<T, P>> where P: FnMut(&T) -> bool {
+ self.split2(pred);
+ loop {}
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs b/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs
new file mode 100644
index 000000000..a04525dcd
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs
@@ -0,0 +1,24 @@
+// run-pass
+// Regression test for issue #21010: Normalize associated types in
+// various special paths in the `type_is_immediate` function.
+
+pub trait OffsetState: Sized {}
+pub trait Offset {
+ type State: OffsetState;
+ fn dummy(&self) { }
+}
+
+#[derive(Copy, Clone)] pub struct X;
+impl Offset for X { type State = Y; }
+
+#[derive(Copy, Clone)] pub struct Y;
+impl OffsetState for Y {}
+
+pub fn now() -> DateTime<X> { from_utc(Y) }
+
+pub struct DateTime<Off: Offset> { pub offset: Off::State }
+pub fn from_utc<Off: Offset>(offset: Off::State) -> DateTime<Off> { DateTime { offset: offset } }
+
+pub fn main() {
+ let _x = now();
+}
diff --git a/src/test/ui/associated-types/associated-types-outlives.rs b/src/test/ui/associated-types/associated-types-outlives.rs
new file mode 100644
index 000000000..55c276280
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-outlives.rs
@@ -0,0 +1,28 @@
+// Regression test for issue #24622. The older associated types code
+// was erroneously assuming that all projections outlived the current
+// fn body, causing this (invalid) code to be accepted.
+
+pub trait Foo<'a> {
+ type Bar;
+}
+
+impl<'a, T:'a> Foo<'a> for T {
+ type Bar = &'a T;
+}
+
+fn denormalise<'a, T>(t: &'a T) -> <T as Foo<'a>>::Bar {
+ t
+}
+
+pub fn free_and_use<T: for<'a> Foo<'a>,
+ F: for<'a> FnOnce(<T as Foo<'a>>::Bar)>(x: T, f: F) {
+ let y;
+ 'body: loop { // lifetime annotations added for clarity
+ 's: loop { y = denormalise(&x); break }
+ drop(x); //~ ERROR cannot move out of `x` because it is borrowed
+ return f(y);
+ }
+}
+
+pub fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-outlives.stderr b/src/test/ui/associated-types/associated-types-outlives.stderr
new file mode 100644
index 000000000..840e33b4b
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-outlives.stderr
@@ -0,0 +1,13 @@
+error[E0505]: cannot move out of `x` because it is borrowed
+ --> $DIR/associated-types-outlives.rs:22:14
+ |
+LL | 's: loop { y = denormalise(&x); break }
+ | -- borrow of `x` occurs here
+LL | drop(x);
+ | ^ move out of `x` occurs here
+LL | return f(y);
+ | - borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
new file mode 100644
index 000000000..109feb8e9
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs
@@ -0,0 +1,8 @@
+#![feature(trait_alias)]
+
+trait I32Iterator = Iterator<Item = i32>;
+
+fn main() {
+ let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
+ //~^ ERROR type mismatch
+}
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
new file mode 100644
index 000000000..dbd9a44ed
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr
@@ -0,0 +1,11 @@
+error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == i32`
+ --> $DIR/associated-types-overridden-binding-2.rs:6:43
+ |
+LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
+ |
+ = note: required for the cast from `std::vec::IntoIter<u32>` to the object type `dyn Iterator<Item = u32, Item = i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.rs b/src/test/ui/associated-types/associated-types-overridden-binding.rs
new file mode 100644
index 000000000..9a64a06c3
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.rs
@@ -0,0 +1,11 @@
+#![feature(trait_alias)]
+
+trait Foo: Iterator<Item = i32> {}
+trait Bar: Foo<Item = u32> {} //~ ERROR type annotations needed
+
+trait I32Iterator = Iterator<Item = i32>;
+trait U32Iterator = I32Iterator<Item = u32>; //~ ERROR type annotations needed
+
+fn main() {
+ let _: &dyn I32Iterator<Item = u32>;
+}
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
new file mode 100644
index 000000000..dc087e418
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
@@ -0,0 +1,27 @@
+error[E0284]: type annotations needed: cannot satisfy `<Self as Iterator>::Item == i32`
+ --> $DIR/associated-types-overridden-binding.rs:4:12
+ |
+LL | trait Bar: Foo<Item = u32> {}
+ | ^^^^^^^^^^^^^^^ cannot satisfy `<Self as Iterator>::Item == i32`
+ |
+note: required by a bound in `Foo`
+ --> $DIR/associated-types-overridden-binding.rs:3:21
+ |
+LL | trait Foo: Iterator<Item = i32> {}
+ | ^^^^^^^^^^ required by this bound in `Foo`
+
+error[E0284]: type annotations needed: cannot satisfy `<Self as Iterator>::Item == i32`
+ --> $DIR/associated-types-overridden-binding.rs:7:21
+ |
+LL | trait U32Iterator = I32Iterator<Item = u32>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Self as Iterator>::Item == i32`
+ |
+note: required by a bound in `I32Iterator`
+ --> $DIR/associated-types-overridden-binding.rs:6:30
+ |
+LL | trait I32Iterator = Iterator<Item = i32>;
+ | ^^^^^^^^^^ required by this bound in `I32Iterator`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/associated-types/associated-types-overridden-default.rs b/src/test/ui/associated-types/associated-types-overridden-default.rs
new file mode 100644
index 000000000..3e12c9228
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-overridden-default.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+// Before RFC 2532, overriding one assoc. type default required overriding all
+// provided defaults.
+
+#![feature(associated_type_defaults)]
+
+pub trait Tr {
+ type Assoc = u8;
+ type Assoc2 = Self::Assoc;
+ const C: u8 = 11;
+ fn foo(&self) {}
+}
+
+impl Tr for () {
+ type Assoc = ();
+}
+
+fn main() {
+ let _: <() as Tr>::Assoc = ();
+ let _: <() as Tr>::Assoc2 = ();
+}
diff --git a/src/test/ui/associated-types/associated-types-path-1.rs b/src/test/ui/associated-types/associated-types-path-1.rs
new file mode 100644
index 000000000..46a5c9e7c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-path-1.rs
@@ -0,0 +1,13 @@
+// Test that we have one and only one associated type per ref.
+
+pub trait Foo {
+ type A;
+}
+pub trait Bar {
+ type A;
+}
+
+pub fn f1<T>(a: T, x: T::A) {} //~ERROR associated type `A` not found
+pub fn f2<T: Foo + Bar>(a: T, x: T::A) {} //~ERROR ambiguous associated type `A`
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-path-1.stderr b/src/test/ui/associated-types/associated-types-path-1.stderr
new file mode 100644
index 000000000..a67f77e37
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-path-1.stderr
@@ -0,0 +1,31 @@
+error[E0220]: associated type `A` not found for `T`
+ --> $DIR/associated-types-path-1.rs:10:26
+ |
+LL | pub fn f1<T>(a: T, x: T::A) {}
+ | ^ associated type `A` not found
+
+error[E0221]: ambiguous associated type `A` in bounds of `T`
+ --> $DIR/associated-types-path-1.rs:11:34
+ |
+LL | type A;
+ | ------ ambiguous `A` from `Foo`
+...
+LL | type A;
+ | ------ ambiguous `A` from `Bar`
+...
+LL | pub fn f2<T: Foo + Bar>(a: T, x: T::A) {}
+ | ^^^^ ambiguous associated type `A`
+ |
+help: use fully qualified syntax to disambiguate
+ |
+LL | pub fn f2<T: Foo + Bar>(a: T, x: <T as Bar>::A) {}
+ | ~~~~~~~~~~~~
+help: use fully qualified syntax to disambiguate
+ |
+LL | pub fn f2<T: Foo + Bar>(a: T, x: <T as Foo>::A) {}
+ | ~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0220, E0221.
+For more information about an error, try `rustc --explain E0220`.
diff --git a/src/test/ui/associated-types/associated-types-path-2.rs b/src/test/ui/associated-types/associated-types-path-2.rs
new file mode 100644
index 000000000..c993e1d27
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-path-2.rs
@@ -0,0 +1,46 @@
+// Test type checking of uses of associated types via sugary paths.
+
+pub trait Foo {
+ type A;
+
+ fn dummy(&self) { }
+}
+
+impl Foo for i32 {
+ type A = u32;
+}
+
+pub fn f1<T: Foo>(a: T, x: T::A) {}
+pub fn f2<T: Foo>(a: T) -> T::A {
+ panic!();
+}
+
+pub fn f1_int_int() {
+ f1(2i32, 4i32);
+ //~^ ERROR mismatched types
+ //~| expected `u32`, found `i32`
+}
+
+pub fn f1_int_uint() {
+ f1(2i32, 4u32);
+}
+
+pub fn f1_uint_uint() {
+ f1(2u32, 4u32);
+ //~^ ERROR `u32: Foo` is not satisfied
+ //~| ERROR `u32: Foo` is not satisfied
+}
+
+pub fn f1_uint_int() {
+ f1(2u32, 4i32);
+ //~^ ERROR `u32: Foo` is not satisfied
+ //~| ERROR `u32: Foo` is not satisfied
+}
+
+pub fn f2_int() {
+ let _: i32 = f2(2i32);
+ //~^ ERROR mismatched types
+ //~| expected `i32`, found `u32`
+}
+
+pub fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr
new file mode 100644
index 000000000..1d0b84d31
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-path-2.stderr
@@ -0,0 +1,79 @@
+error[E0308]: mismatched types
+ --> $DIR/associated-types-path-2.rs:19:14
+ |
+LL | f1(2i32, 4i32);
+ | -- ^^^^ expected `u32`, found `i32`
+ | |
+ | arguments to this function are incorrect
+ |
+note: function defined here
+ --> $DIR/associated-types-path-2.rs:13:8
+ |
+LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
+ | ^^ ---- -------
+help: change the type of the numeric literal from `i32` to `u32`
+ |
+LL | f1(2i32, 4u32);
+ | ~~~
+
+error[E0277]: the trait bound `u32: Foo` is not satisfied
+ --> $DIR/associated-types-path-2.rs:29:5
+ |
+LL | f1(2u32, 4u32);
+ | ^^ the trait `Foo` is not implemented for `u32`
+ |
+ = help: the trait `Foo` is implemented for `i32`
+note: required by a bound in `f1`
+ --> $DIR/associated-types-path-2.rs:13:14
+ |
+LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
+ | ^^^ required by this bound in `f1`
+
+error[E0277]: the trait bound `u32: Foo` is not satisfied
+ --> $DIR/associated-types-path-2.rs:29:14
+ |
+LL | f1(2u32, 4u32);
+ | ^^^^ the trait `Foo` is not implemented for `u32`
+ |
+ = help: the trait `Foo` is implemented for `i32`
+
+error[E0277]: the trait bound `u32: Foo` is not satisfied
+ --> $DIR/associated-types-path-2.rs:35:8
+ |
+LL | f1(2u32, 4i32);
+ | -- ^^^^ the trait `Foo` is not implemented for `u32`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `Foo` is implemented for `i32`
+note: required by a bound in `f1`
+ --> $DIR/associated-types-path-2.rs:13:14
+ |
+LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
+ | ^^^ required by this bound in `f1`
+
+error[E0277]: the trait bound `u32: Foo` is not satisfied
+ --> $DIR/associated-types-path-2.rs:35:14
+ |
+LL | f1(2u32, 4i32);
+ | ^^^^ the trait `Foo` is not implemented for `u32`
+ |
+ = help: the trait `Foo` is implemented for `i32`
+
+error[E0308]: mismatched types
+ --> $DIR/associated-types-path-2.rs:41:18
+ |
+LL | let _: i32 = f2(2i32);
+ | --- ^^^^^^^^ expected `i32`, found `u32`
+ | |
+ | expected due to this
+ |
+help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
+ |
+LL | let _: i32 = f2(2i32).try_into().unwrap();
+ | ++++++++++++++++++++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs
new file mode 100644
index 000000000..069bf5600
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs
@@ -0,0 +1,27 @@
+// Check projection of an associated type out of a higher-ranked
+// trait-bound in the context of a function body.
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+fn foo<'a, I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&'a isize>>::A)
+{
+ let y: I::A = x;
+}
+
+fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&'a isize>>::A,
+ y: <I as Foo<&'b isize>>::A,
+ cond: bool)
+{
+ // x and y here have two distinct lifetimes:
+ let z: I::A = if cond { x } else { y };
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR lifetime may not live long enough
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr
new file mode 100644
index 000000000..e12d42e5e
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr
@@ -0,0 +1,30 @@
+error: lifetime may not live long enough
+ --> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:29
+ |
+LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let z: I::A = if cond { x } else { y };
+ | ^ assignment requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:40
+ |
+LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let z: I::A = if cond { x } else { y };
+ | ^ assignment requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
new file mode 100644
index 000000000..bca69a976
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed
@@ -0,0 +1,37 @@
+#![allow(dead_code, unused_variables)]
+// run-rustfix
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a function signature.
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+fn foo2<I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&isize>>::A)
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+{
+ // This case is illegal because we have to instantiate `'x`, and
+ // we don't know what region to instantiate it with.
+ //
+ // This could perhaps be made equivalent to the examples below,
+ // specifically for fn signatures.
+}
+
+fn foo3<I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&isize>>::A)
+{
+ // OK, in this case we spelled out the precise regions involved, though we left one of
+ // them anonymous.
+}
+
+fn foo4<'a, I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&'a isize>>::A)
+{
+ // OK, in this case we spelled out the precise regions involved.
+}
+
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
new file mode 100644
index 000000000..1e23dd889
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs
@@ -0,0 +1,37 @@
+#![allow(dead_code, unused_variables)]
+// run-rustfix
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a function signature.
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+fn foo2<I : for<'x> Foo<&'x isize>>(
+ x: I::A)
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+{
+ // This case is illegal because we have to instantiate `'x`, and
+ // we don't know what region to instantiate it with.
+ //
+ // This could perhaps be made equivalent to the examples below,
+ // specifically for fn signatures.
+}
+
+fn foo3<I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&isize>>::A)
+{
+ // OK, in this case we spelled out the precise regions involved, though we left one of
+ // them anonymous.
+}
+
+fn foo4<'a, I : for<'x> Foo<&'x isize>>(
+ x: <I as Foo<&'a isize>>::A)
+{
+ // OK, in this case we spelled out the precise regions involved.
+}
+
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
new file mode 100644
index 000000000..c508006c3
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr
@@ -0,0 +1,14 @@
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-fn.rs:13:8
+ |
+LL | x: I::A)
+ | ^^^^
+ |
+help: use a fully qualified path with inferred lifetimes
+ |
+LL | x: <I as Foo<&isize>>::A)
+ | ~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0212`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
new file mode 100644
index 000000000..ed30d86cb
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs
@@ -0,0 +1,39 @@
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a struct definition.
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+struct SomeStruct<I: for<'x> Foo<&'x isize>> {
+ field: I::A
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+}
+
+enum SomeEnum<'b, I: for<'a> Foo<&'a isize>> {
+ TupleVariant(I::A),
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+ StructVariant { field: I::A },
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+ OkVariant(&'b usize),
+}
+
+// FIXME(eddyb) This one doesn't even compile because of the unsupported syntax.
+
+// struct AnotherStruct<I : for<'x> Foo<&'x isize>> {
+// field: <I as for<'y> Foo<&'y isize>>::A
+// }
+
+struct YetAnotherStruct<'a, I: for<'x> Foo<&'x isize>> {
+ field: <I as Foo<&'a isize>>::A,
+}
+
+struct Why<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x,
+ 'y, 'z, 'aa, I: for<'l, 'm> Foo<&'l &'m isize>> {
+ field: I::A,
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
new file mode 100644
index 000000000..62a619723
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr
@@ -0,0 +1,54 @@
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-struct.rs:11:12
+ |
+LL | field: I::A
+ | ^^^^
+ |
+help: use a fully qualified path with explicit lifetimes
+ |
+LL ~ struct SomeStruct<'a, I: for<'x> Foo<&'x isize>> {
+LL ~ field: <I as Foo<&'a isize>>::A
+ |
+
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-struct.rs:16:18
+ |
+LL | TupleVariant(I::A),
+ | ^^^^
+ |
+help: use a fully qualified path with explicit lifetimes
+ |
+LL ~ enum SomeEnum<'c, 'b, I: for<'a> Foo<&'a isize>> {
+LL ~ TupleVariant(<I as Foo<&'c isize>>::A),
+ |
+
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-struct.rs:18:28
+ |
+LL | StructVariant { field: I::A },
+ | ^^^^
+ |
+help: use a fully qualified path with explicit lifetimes
+ |
+LL ~ enum SomeEnum<'c, 'b, I: for<'a> Foo<&'a isize>> {
+LL | TupleVariant(I::A),
+LL |
+LL ~ StructVariant { field: <I as Foo<&'c isize>>::A },
+ |
+
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-struct.rs:35:12
+ |
+LL | field: I::A,
+ | ^^^^
+ |
+help: use a fully qualified path with explicit lifetimes
+ |
+LL ~ struct Why<'bb, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x,
+LL | 'y, 'z, 'aa, I: for<'l, 'm> Foo<&'l &'m isize>> {
+LL ~ field: <I as Foo<&'bb &'bb isize>>::A,
+ |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0212`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
new file mode 100644
index 000000000..66d8613f1
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed
@@ -0,0 +1,38 @@
+#![allow(dead_code)]
+// run-rustfix
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a method definition in a trait.
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+trait SomeTrait<I : for<'x> Foo<&'x isize>> {
+ fn some_method(&self, arg: <I as Foo<&isize>>::A);
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+}
+
+trait AnotherTrait<I : for<'x> Foo<&'x isize>> {
+ fn some_method(&self, arg: <I as Foo<&isize>>::A);
+}
+
+trait YetAnotherTrait<I : for<'x> Foo<&'x isize>> {
+ fn some_method<'a>(&self, arg: <I as Foo<&'a isize>>::A);
+}
+
+trait Banana<'a> {
+ type Assoc: Default;
+}
+
+struct Peach<X>(std::marker::PhantomData<X>);
+
+impl<X: for<'a> Banana<'a>> Peach<X> {
+ fn mango(&self) -> <X as Banana<'_>>::Assoc {
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+ Default::default()
+ }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
new file mode 100644
index 000000000..0a1b29de1
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs
@@ -0,0 +1,38 @@
+#![allow(dead_code)]
+// run-rustfix
+// Check projection of an associated type out of a higher-ranked trait-bound
+// in the context of a method definition in a trait.
+
+pub trait Foo<T> {
+ type A;
+
+ fn get(&self, t: T) -> Self::A;
+}
+
+trait SomeTrait<I : for<'x> Foo<&'x isize>> {
+ fn some_method(&self, arg: I::A);
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+}
+
+trait AnotherTrait<I : for<'x> Foo<&'x isize>> {
+ fn some_method(&self, arg: <I as Foo<&isize>>::A);
+}
+
+trait YetAnotherTrait<I : for<'x> Foo<&'x isize>> {
+ fn some_method<'a>(&self, arg: <I as Foo<&'a isize>>::A);
+}
+
+trait Banana<'a> {
+ type Assoc: Default;
+}
+
+struct Peach<X>(std::marker::PhantomData<X>);
+
+impl<X: for<'a> Banana<'a>> Peach<X> {
+ fn mango(&self) -> X::Assoc {
+ //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters
+ Default::default()
+ }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
new file mode 100644
index 000000000..48433b152
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr
@@ -0,0 +1,25 @@
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:13:32
+ |
+LL | fn some_method(&self, arg: I::A);
+ | ^^^^
+ |
+help: use a fully qualified path with inferred lifetimes
+ |
+LL | fn some_method(&self, arg: <I as Foo<&isize>>::A);
+ | ~~~~~~~~~~~~~~~~~~~~
+
+error[E0212]: cannot use the associated type of a trait with uninferred generic parameters
+ --> $DIR/associated-types-project-from-hrtb-in-trait-method.rs:32:24
+ |
+LL | fn mango(&self) -> X::Assoc {
+ | ^^^^^^^^
+ |
+help: use a fully qualified path with inferred lifetimes
+ |
+LL | fn mango(&self) -> <X as Banana<'_>>::Assoc {
+ | ~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0212`.
diff --git a/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs b/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs
new file mode 100644
index 000000000..fc1dba97d
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs
@@ -0,0 +1,98 @@
+// run-pass
+// Various uses of `T::Item` syntax where the bound that supplies
+// `Item` originates in a where-clause, not the declaration of
+// `T`. Issue #20300.
+
+use std::marker::{PhantomData};
+use std::sync::atomic::{AtomicUsize};
+use std::sync::atomic::Ordering::SeqCst;
+
+static COUNTER: AtomicUsize = AtomicUsize::new(0);
+
+// Preamble.
+trait Trait { type Item; }
+struct Struct;
+impl Trait for Struct {
+ type Item = u32;
+}
+
+// Where-clause attached on the method which declares `T`.
+struct A;
+impl A {
+ fn foo<T>(_x: T::Item) where T: Trait {
+ COUNTER.fetch_add(1, SeqCst);
+ }
+}
+
+// Where-clause attached on the method to a parameter from the struct.
+struct B<T>(PhantomData<T>);
+impl<T> B<T> {
+ fn foo(_x: T::Item) where T: Trait {
+ COUNTER.fetch_add(10, SeqCst);
+ }
+}
+
+// Where-clause attached to free fn.
+fn c<T>(_: T::Item) where T : Trait {
+ COUNTER.fetch_add(100, SeqCst);
+}
+
+// Where-clause attached to defaulted and non-defaulted trait method.
+trait AnotherTrait {
+ fn method<T>(&self, _: T::Item) where T: Trait;
+ fn default_method<T>(&self, _: T::Item) where T: Trait {
+ COUNTER.fetch_add(1000, SeqCst);
+ }
+}
+struct D;
+impl AnotherTrait for D {
+ fn method<T>(&self, _: T::Item) where T: Trait {
+ COUNTER.fetch_add(10000, SeqCst);
+ }
+}
+
+// Where-clause attached to trait and impl containing the method.
+trait YetAnotherTrait<T>
+ where T : Trait
+{
+ fn method(&self, _: T::Item);
+ fn default_method(&self, _: T::Item) {
+ COUNTER.fetch_add(100000, SeqCst);
+ }
+}
+struct E<T>(PhantomData<T>);
+impl<T> YetAnotherTrait<T> for E<T>
+ where T : Trait
+{
+ fn method(&self, _: T::Item) {
+ COUNTER.fetch_add(1000000, SeqCst);
+ }
+}
+
+// Where-clause attached to inherent impl containing the method.
+struct F<T>(PhantomData<T>);
+impl<T> F<T> where T : Trait {
+ fn method(&self, _: T::Item) {
+ COUNTER.fetch_add(10000000, SeqCst);
+ }
+}
+
+// Where-clause attached to struct.
+#[allow(dead_code)]
+struct G<T> where T : Trait {
+ data: T::Item,
+ phantom: PhantomData<T>,
+}
+
+fn main() {
+ A::foo::<Struct>(22);
+ B::<Struct>::foo(22);
+ c::<Struct>(22);
+ D.method::<Struct>(22);
+ D.default_method::<Struct>(22);
+ E(PhantomData::<Struct>).method(22);
+ E(PhantomData::<Struct>).default_method(22);
+ F(PhantomData::<Struct>).method(22);
+ G::<Struct> { data: 22, phantom: PhantomData };
+ assert_eq!(COUNTER.load(SeqCst), 11111111);
+}
diff --git a/src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs b/src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs
new file mode 100644
index 000000000..353f82e7c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs
@@ -0,0 +1,16 @@
+// Check that if we have multiple applicable projection bounds we pick one (for
+// backwards compatibility reasons).
+
+// check-pass
+use std::ops::Mul;
+
+trait A {
+ type V;
+ type U: Mul<Self::V, Output = ()> + Mul<(), Output = ()>;
+}
+
+fn g<T: A<V = ()>>() {
+ let y: <T::U as Mul<()>>::Output = ();
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs b/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs
new file mode 100644
index 000000000..107e6b4ce
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(unused_variables)]
+// Test that we correctly handle projection bounds appearing in the
+// supertrait list (and in conjunction with overloaded operators). In
+// this case, the `Result=Self` binding in the supertrait listing of
+// `Int` was being ignored.
+
+trait Not {
+ type Result;
+
+ fn not(self) -> Self::Result;
+}
+
+trait Int: Not<Result=Self> + Sized {
+ fn count_ones(self) -> usize;
+ fn count_zeros(self) -> usize {
+ // neither works
+ let x: Self = self.not();
+ 0
+ }
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs b/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs
new file mode 100644
index 000000000..a59c327be
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs
@@ -0,0 +1,38 @@
+// run-pass
+// Test where the impl self type uses a projection from a constant type.
+
+
+trait Int
+{
+ type T;
+
+ fn dummy(&self) { }
+}
+
+trait NonZero
+{
+ fn non_zero(self) -> bool;
+}
+
+impl Int for i32 { type T = i32; }
+impl Int for i64 { type T = i64; }
+impl Int for u32 { type T = u32; }
+impl Int for u64 { type T = u64; }
+
+impl NonZero for <i32 as Int>::T { fn non_zero(self) -> bool { self != 0 } }
+impl NonZero for <i64 as Int>::T { fn non_zero(self) -> bool { self != 0 } }
+impl NonZero for <u32 as Int>::T { fn non_zero(self) -> bool { self != 0 } }
+impl NonZero for <u64 as Int>::T { fn non_zero(self) -> bool { self != 0 } }
+
+fn main ()
+{
+ assert!(NonZero::non_zero(22_i32));
+ assert!(NonZero::non_zero(22_i64));
+ assert!(NonZero::non_zero(22_u32));
+ assert!(NonZero::non_zero(22_u64));
+
+ assert!(!NonZero::non_zero(0_i32));
+ assert!(!NonZero::non_zero(0_i64));
+ assert!(!NonZero::non_zero(0_u32));
+ assert!(!NonZero::non_zero(0_u64));
+}
diff --git a/src/test/ui/associated-types/associated-types-projection-in-object-type.rs b/src/test/ui/associated-types/associated-types-projection-in-object-type.rs
new file mode 100644
index 000000000..eec95a141
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-in-object-type.rs
@@ -0,0 +1,40 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_imports)]
+// Corrected regression test for #20831. The original did not compile.
+// When fixed, it revealed another problem concerning projections that
+// appear in associated type bindings in object types, which were not
+// being properly flagged.
+
+// pretty-expanded FIXME #23616
+
+use std::ops::{Shl, Shr};
+use std::cell::RefCell;
+
+pub trait Subscriber {
+ type Input;
+
+ fn dummy(&self) { }
+}
+
+pub trait Publisher<'a> {
+ type Output;
+ fn subscribe(&mut self, _: Box<dyn Subscriber<Input=Self::Output> + 'a>);
+}
+
+pub trait Processor<'a> : Subscriber + Publisher<'a> { }
+
+impl<'a, P> Processor<'a> for P where P : Subscriber + Publisher<'a> { }
+
+struct MyStruct<'a> {
+ sub: Box<dyn Subscriber<Input=u64> + 'a>
+}
+
+impl<'a> Publisher<'a> for MyStruct<'a> {
+ type Output = u64;
+ fn subscribe(&mut self, t : Box<dyn Subscriber<Input=u64> + 'a>) {
+ self.sub = t;
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs b/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs
new file mode 100644
index 000000000..ead405fcf
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-in-supertrait.rs
@@ -0,0 +1,45 @@
+// run-pass
+#![allow(dead_code)]
+// Test that we are handle to correctly handle a projection type
+// that appears in a supertrait bound. Issue #20559.
+
+
+trait A
+{
+ type TA;
+
+ fn dummy(&self) { }
+}
+
+trait B<TB>
+{
+ fn foo (&self, t : TB) -> String;
+}
+
+trait C<TC : A> : B<<TC as A>::TA> { }
+
+struct X;
+
+impl A for X
+{
+ type TA = i32;
+}
+
+struct Y;
+
+impl C<X> for Y { }
+
+// Both of these impls are required for successful compilation
+impl B<i32> for Y
+{
+ fn foo (&self, t : i32) -> String
+ {
+ format!("First {}", t)
+ }
+}
+
+fn main ()
+{
+ let y = Y;
+ assert_eq!(y.foo(5), format!("First 5"));
+}
diff --git a/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs b/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs
new file mode 100644
index 000000000..e9a26e53c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-in-where-clause.rs
@@ -0,0 +1,31 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+// Test a where clause that uses a non-normalized projection type.
+
+// pretty-expanded FIXME #23616
+
+trait Int
+{
+ type T;
+
+ fn dummy(&self) { }
+}
+
+trait NonZero
+{
+ fn non_zero(self) -> bool;
+}
+
+fn foo<I:Int<T=J>,J>(t: I) -> bool
+ where <I as Int>::T : NonZero
+ // ^~~~~~~~~~~~~ canonical form is just J
+{
+ bar::<J>()
+}
+
+fn bar<NZ:NonZero>() -> bool { true }
+
+fn main ()
+{
+}
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed
new file mode 100644
index 000000000..9bc308465
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed
@@ -0,0 +1,30 @@
+// run-rustfix
+// Check that we get an error when you use `<Self as Get>::Value` in
+// the trait definition even if there is no default method.
+
+trait Get {
+ type Value;
+}
+
+trait Other {
+ fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get;
+ //~^ ERROR E0277
+}
+
+impl Get for () {
+ type Value = f32;
+}
+
+impl Get for f64 {
+ type Value = u32;
+}
+
+impl Other for () {
+ fn okay<U:Get>(&self, _foo: U, _bar: <Self as Get>::Value) { }
+}
+
+impl Other for f64 {
+ fn okay<U:Get>(&self, _foo: U, _bar: <Self as Get>::Value) { }
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs
new file mode 100644
index 000000000..549fc8fc6
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs
@@ -0,0 +1,30 @@
+// run-rustfix
+// Check that we get an error when you use `<Self as Get>::Value` in
+// the trait definition even if there is no default method.
+
+trait Get {
+ type Value;
+}
+
+trait Other {
+ fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
+ //~^ ERROR E0277
+}
+
+impl Get for () {
+ type Value = f32;
+}
+
+impl Get for f64 {
+ type Value = u32;
+}
+
+impl Other for () {
+ fn okay<U:Get>(&self, _foo: U, _bar: <Self as Get>::Value) { }
+}
+
+impl Other for f64 {
+ fn okay<U:Get>(&self, _foo: U, _bar: <Self as Get>::Value) { }
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
new file mode 100644
index 000000000..2e67c2194
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `Self: Get` is not satisfied
+ --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
+ |
+LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
+ |
+help: consider further restricting `Self`
+ |
+LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value) where Self: Get;
+ | +++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
new file mode 100644
index 000000000..3b8c8c019
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
@@ -0,0 +1,35 @@
+// run-pass
+// Check that we do not get an error when you use `<Self as Get>::Value` in
+// the trait definition if there is no default method and for every impl,
+// `Self` does implement `Get`.
+//
+// See also tests associated-types-no-suitable-supertrait
+// and associated-types-no-suitable-supertrait-2, which show how small
+// variants of the code below can fail.
+
+trait Get {
+ type Value;
+}
+
+trait Other {
+ fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value)
+ where Self: Get;
+}
+
+impl Get for () {
+ type Value = f32;
+}
+
+impl Get for f64 {
+ type Value = u32;
+}
+
+impl Other for () {
+ fn okay<U:Get>(&self, _foo: U, _bar: <Self as Get>::Value) { }
+}
+
+impl Other for f64 {
+ fn okay<U:Get>(&self, _foo: U, _bar: <Self as Get>::Value) { }
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
new file mode 100644
index 000000000..3c830d370
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
@@ -0,0 +1,9 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+trait Foo<T> {
+ type Bar;
+ fn get_bar() -> <Self as Foo<T>>::Bar;
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-ref-from-struct.rs b/src/test/ui/associated-types/associated-types-ref-from-struct.rs
new file mode 100644
index 000000000..c89f6046e
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-ref-from-struct.rs
@@ -0,0 +1,51 @@
+// run-pass
+// Test associated type references in structure fields.
+
+// pretty-expanded FIXME #23616
+
+trait Test {
+ type V;
+
+ fn test(&self, value: &Self::V) -> bool;
+}
+
+struct TesterPair<T:Test> {
+ tester: T,
+ value: T::V,
+}
+
+impl<T:Test> TesterPair<T> {
+ fn new(tester: T, value: T::V) -> TesterPair<T> {
+ TesterPair { tester: tester, value: value }
+ }
+
+ fn test(&self) -> bool {
+ self.tester.test(&self.value)
+ }
+}
+
+struct EqU32(u32);
+impl Test for EqU32 {
+ type V = u32;
+
+ fn test(&self, value: &u32) -> bool {
+ self.0 == *value
+ }
+}
+
+struct EqI32(i32);
+impl Test for EqI32 {
+ type V = i32;
+
+ fn test(&self, value: &i32) -> bool {
+ self.0 == *value
+ }
+}
+
+fn main() {
+ let tester = TesterPair::new(EqU32(22), 23);
+ tester.test();
+
+ let tester = TesterPair::new(EqI32(22), 23);
+ tester.test();
+}
diff --git a/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs b/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs
new file mode 100644
index 000000000..4a490ed03
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs
@@ -0,0 +1,23 @@
+// run-pass
+// Test associated type references in a struct literal. Issue #20535.
+
+
+pub trait Foo {
+ type Bar;
+
+ fn dummy(&self) { }
+}
+
+impl Foo for isize {
+ type Bar = isize;
+}
+
+struct Thing<F: Foo> {
+ a: F,
+ b: F::Bar,
+}
+
+fn main() {
+ let thing = Thing{a: 1, b: 2};
+ assert_eq!(thing.a + 1, thing.b);
+}
diff --git a/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs b/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs
new file mode 100644
index 000000000..b722506db
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![allow(dead_code)]
+// Regression test for #20582. This test caused an ICE related to
+// inconsistent region erasure in codegen.
+
+// pretty-expanded FIXME #23616
+
+struct Foo<'a> {
+ buf: &'a[u8]
+}
+
+impl<'a> Iterator for Foo<'a> {
+ type Item = &'a[u8];
+
+ fn next(&mut self) -> Option<<Self as Iterator>::Item> {
+ Some(self.buf)
+ }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-resolve-lifetime.rs b/src/test/ui/associated-types/associated-types-resolve-lifetime.rs
new file mode 100644
index 000000000..52f2324d7
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-resolve-lifetime.rs
@@ -0,0 +1,15 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+trait Get<T> {
+ fn get(&self) -> T;
+}
+
+trait Trait<'a> {
+ type T: 'static;
+ type U: Get<&'a isize>;
+
+ fn dummy(&'a self) { }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-return.rs b/src/test/ui/associated-types/associated-types-return.rs
new file mode 100644
index 000000000..997a48b03
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-return.rs
@@ -0,0 +1,46 @@
+// run-pass
+// Test equality constraints on associated types in a where clause.
+
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> <Self as Foo>::A;
+}
+
+#[derive(PartialEq, Debug)]
+pub struct Bar;
+
+impl Foo for isize {
+ type A = usize;
+ fn boo(&self) -> usize { 42 }
+}
+
+impl Foo for Bar {
+ type A = isize;
+ fn boo(&self) -> isize { 43 }
+}
+
+impl Foo for char {
+ type A = Bar;
+ fn boo(&self) -> Bar { Bar }
+}
+
+fn foo1<I: Foo<A=Bar>>(x: I) -> Bar {
+ x.boo()
+}
+
+fn foo2<I: Foo>(x: I) -> <I as Foo>::A {
+ x.boo()
+}
+
+pub fn main() {
+ let a = 42;
+ assert_eq!(foo2(a), 42);
+
+ let a = Bar;
+ assert_eq!(foo2(a), 43);
+
+ let a = 'a';
+ foo1(a);
+ assert_eq!(foo2(a), Bar);
+}
diff --git a/src/test/ui/associated-types/associated-types-simple.rs b/src/test/ui/associated-types/associated-types-simple.rs
new file mode 100644
index 000000000..2e2dfd807
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-simple.rs
@@ -0,0 +1,24 @@
+// run-pass
+
+trait Get {
+ type Value;
+ fn get(&self) -> &<Self as Get>::Value;
+}
+
+struct Struct {
+ x: isize,
+}
+
+impl Get for Struct {
+ type Value = isize;
+ fn get(&self) -> &isize {
+ &self.x
+ }
+}
+
+fn main() {
+ let s = Struct {
+ x: 100,
+ };
+ assert_eq!(*s.get(), 100);
+}
diff --git a/src/test/ui/associated-types/associated-types-stream.rs b/src/test/ui/associated-types/associated-types-stream.rs
new file mode 100644
index 000000000..c9b302b96
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-stream.rs
@@ -0,0 +1,38 @@
+// run-pass
+// Test references to the trait `Stream` in the bounds for associated
+// types defined on `Stream`. Issue #20551.
+
+trait Stream {
+ type Car;
+ type Cdr: Stream;
+
+ fn car(&self) -> Self::Car;
+ fn cdr(self) -> Self::Cdr;
+}
+
+impl Stream for () {
+ type Car = ();
+ type Cdr = ();
+ fn car(&self) -> () { () }
+ fn cdr(self) -> () { self }
+}
+
+impl<T,U> Stream for (T, U)
+ where T : Clone, U : Stream
+{
+ type Car = T;
+ type Cdr = U;
+ fn car(&self) -> T { self.0.clone() }
+ fn cdr(self) -> U { self.1 }
+}
+
+fn main() {
+ let p = (22, (44, (66, ())));
+ assert_eq!(p.car(), 22);
+
+ let p = p.cdr();
+ assert_eq!(p.car(), 44);
+
+ let p = p.cdr();
+ assert_eq!(p.car(), 66);
+}
diff --git a/src/test/ui/associated-types/associated-types-struct-field-named.rs b/src/test/ui/associated-types/associated-types-struct-field-named.rs
new file mode 100644
index 000000000..c400bf943
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-struct-field-named.rs
@@ -0,0 +1,35 @@
+// run-pass
+// Test that we correctly normalize the type of a struct field
+// which has an associated type.
+
+
+pub trait UnifyKey {
+ type Value;
+
+ fn dummy(&self) { }
+}
+
+pub struct Node<K:UnifyKey> {
+ pub key: K,
+ pub value: K::Value,
+}
+
+fn foo<K : UnifyKey<Value=Option<V>>,V : Clone>(node: &Node<K>) -> Option<V> {
+ node.value.clone()
+}
+
+impl UnifyKey for i32 {
+ type Value = Option<u32>;
+}
+
+impl UnifyKey for u32 {
+ type Value = Option<i32>;
+}
+
+pub fn main() {
+ let node: Node<i32> = Node { key: 1, value: Some(22) };
+ assert_eq!(foo(&node), Some(22));
+
+ let node: Node<u32> = Node { key: 1, value: Some(22) };
+ assert_eq!(foo(&node), Some(22));
+}
diff --git a/src/test/ui/associated-types/associated-types-struct-field-numbered.rs b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs
new file mode 100644
index 000000000..8612911d8
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-struct-field-numbered.rs
@@ -0,0 +1,32 @@
+// run-pass
+// Test that we correctly normalize the type of a struct field
+// which has an associated type.
+
+
+pub trait UnifyKey {
+ type Value;
+
+ fn dummy(&self) { }
+}
+
+pub struct Node<K:UnifyKey>(#[allow(unused_tuple_struct_fields)] K, K::Value);
+
+fn foo<K : UnifyKey<Value=Option<V>>,V : Clone>(node: &Node<K>) -> Option<V> {
+ node.1.clone()
+}
+
+impl UnifyKey for i32 {
+ type Value = Option<u32>;
+}
+
+impl UnifyKey for u32 {
+ type Value = Option<i32>;
+}
+
+pub fn main() {
+ let node: Node<i32> = Node(1, Some(22));
+ assert_eq!(foo(&node), Some(22));
+
+ let node: Node<u32> = Node(1, Some(22));
+ assert_eq!(foo(&node), Some(22));
+}
diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.rs b/src/test/ui/associated-types/associated-types-subtyping-1.rs
new file mode 100644
index 000000000..c4758f255
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-subtyping-1.rs
@@ -0,0 +1,49 @@
+#![allow(unused_variables)]
+
+fn make_any<T>() -> T { loop {} }
+
+trait Trait<'a> {
+ type Type;
+
+ fn method(&'a self) { }
+}
+
+fn method1<'a,'b,T>(x: &'a T, y: &'b T)
+ where T : for<'z> Trait<'z>, 'a : 'b
+{
+ // Note that &'static T <: &'a T.
+ let a: <T as Trait<'a>>::Type = make_any();
+ let b: <T as Trait<'b>>::Type = make_any();
+ let _c: <T as Trait<'a>>::Type = a;
+}
+
+fn method2<'a,'b,T>(x: &'a T, y: &'b T)
+ where T : for<'z> Trait<'z>, 'a : 'b
+{
+ // Note that &'static T <: &'a T.
+ let a: <T as Trait<'a>>::Type = make_any();
+ //~^ ERROR lifetime may not live long enough
+ let b: <T as Trait<'b>>::Type = make_any();
+ let _c: <T as Trait<'b>>::Type = a;
+}
+
+fn method3<'a,'b,T>(x: &'a T, y: &'b T)
+ where T : for<'z> Trait<'z>, 'a : 'b
+{
+ // Note that &'static T <: &'a T.
+ let a: <T as Trait<'a>>::Type = make_any();
+ let b: <T as Trait<'b>>::Type = make_any();
+ let _c: <T as Trait<'a>>::Type = b;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn method4<'a,'b,T>(x: &'a T, y: &'b T)
+ where T : for<'z> Trait<'z>, 'a : 'b
+{
+ // Note that &'static T <: &'a T.
+ let a: <T as Trait<'a>>::Type = make_any();
+ let b: <T as Trait<'b>>::Type = make_any();
+ let _c: <T as Trait<'b>>::Type = b;
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/associated-types-subtyping-1.stderr b/src/test/ui/associated-types/associated-types-subtyping-1.stderr
new file mode 100644
index 000000000..414bc048a
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-subtyping-1.stderr
@@ -0,0 +1,28 @@
+error: lifetime may not live long enough
+ --> $DIR/associated-types-subtyping-1.rs:24:12
+ |
+LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T)
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let a: <T as Trait<'a>>::Type = make_any();
+ | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+ --> $DIR/associated-types-subtyping-1.rs:36:13
+ |
+LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T)
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _c: <T as Trait<'a>>::Type = b;
+ | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/associated-types-sugar-path.rs b/src/test/ui/associated-types/associated-types-sugar-path.rs
new file mode 100644
index 000000000..66f7672aa
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-sugar-path.rs
@@ -0,0 +1,41 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_imports)]
+// Test paths to associated types using the type-parameter-only sugar.
+
+use std::ops::Deref;
+
+pub trait Foo {
+ type A;
+ fn boo(&self) -> Self::A;
+}
+
+impl Foo for isize {
+ type A = usize;
+ fn boo(&self) -> usize {
+ 5
+ }
+}
+
+// Using a type via a function.
+pub fn bar<T: Foo>(a: T, x: T::A) -> T::A {
+ let _: T::A = a.boo();
+ x
+}
+
+// Using a type via an impl.
+trait C {
+ fn f();
+ fn g(&self) { }
+}
+struct B<X>(X);
+impl<T: Foo> C for B<T> {
+ fn f() {
+ let x: T::A = panic!();
+ }
+}
+
+pub fn main() {
+ let z: usize = bar(2, 4);
+}
diff --git a/src/test/ui/associated-types/associated-types-unconstrained.rs b/src/test/ui/associated-types/associated-types-unconstrained.rs
new file mode 100644
index 000000000..2fb27bf3c
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-unconstrained.rs
@@ -0,0 +1,16 @@
+// Check that an associated type cannot be bound in an expression path.
+
+trait Foo {
+ type A;
+ fn bar() -> isize;
+}
+
+impl Foo for isize {
+ type A = usize;
+ fn bar() -> isize { 42 }
+}
+
+pub fn main() {
+ let x: isize = Foo::bar();
+ //~^ ERROR E0790
+}
diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr
new file mode 100644
index 000000000..e51a8f3bd
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr
@@ -0,0 +1,12 @@
+error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
+ --> $DIR/associated-types-unconstrained.rs:14:20
+ |
+LL | fn bar() -> isize;
+ | ------------------ `Foo::bar` defined here
+...
+LL | let x: isize = Foo::bar();
+ | ^^^^^^^^ cannot call associated function of trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0790`.
diff --git a/src/test/ui/associated-types/associated-types-unsized.fixed b/src/test/ui/associated-types/associated-types-unsized.fixed
new file mode 100644
index 000000000..328c8f944
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-unsized.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+trait Get {
+ type Value: ?Sized;
+ fn get(&self) -> <Self as Get>::Value;
+}
+
+fn foo<T:Get>(t: T) where <T as Get>::Value: Sized {
+ let x = t.get(); //~ ERROR the size for values of type
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-unsized.rs b/src/test/ui/associated-types/associated-types-unsized.rs
new file mode 100644
index 000000000..bdba4c7ff
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-unsized.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+#![allow(dead_code, unused_variables)]
+
+trait Get {
+ type Value: ?Sized;
+ fn get(&self) -> <Self as Get>::Value;
+}
+
+fn foo<T:Get>(t: T) {
+ let x = t.get(); //~ ERROR the size for values of type
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/associated-types-unsized.stderr b/src/test/ui/associated-types/associated-types-unsized.stderr
new file mode 100644
index 000000000..bec9b1500
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-unsized.stderr
@@ -0,0 +1,17 @@
+error[E0277]: the size for values of type `<T as Get>::Value` cannot be known at compilation time
+ --> $DIR/associated-types-unsized.rs:10:9
+ |
+LL | let x = t.get();
+ | ^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `<T as Get>::Value`
+ = note: all local variables must have a statically known size
+ = help: unsized locals are gated as an unstable feature
+help: consider further restricting the associated type
+ |
+LL | fn foo<T:Get>(t: T) where <T as Get>::Value: Sized {
+ | ++++++++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs b/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs
new file mode 100644
index 000000000..f2a4c6e42
--- /dev/null
+++ b/src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs
@@ -0,0 +1,46 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_imports)]
+// Test how resolving a projection interacts with inference. In this
+// case, we were eagerly unifying the type variable for the iterator
+// type with `I` from the where clause, ignoring the in-scope `impl`
+// for `ByRef`. The right answer was to consider the result ambiguous
+// until more type information was available.
+
+#![feature(lang_items)]
+#![no_implicit_prelude]
+
+use std::marker::Sized;
+use std::option::Option::{None, Some, self};
+
+trait Iterator {
+ type Item;
+
+ fn next(&mut self) -> Option<Self::Item>;
+}
+
+trait IteratorExt: Iterator + Sized {
+ fn by_ref(&mut self) -> ByRef<Self> {
+ ByRef(self)
+ }
+}
+
+impl<I> IteratorExt for I where I: Iterator {}
+
+struct ByRef<'a, I: 'a + Iterator>(&'a mut I);
+
+impl<'a, A, I> Iterator for ByRef<'a, I> where I: Iterator<Item=A> {
+ type Item = A;
+
+ fn next(&mut self) -> Option< <I as Iterator>::Item > {
+ self.0.next()
+ }
+}
+
+fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
+
+fn test<A, I: Iterator<Item=A>>(mut it: I) {
+ is_iterator_of::<A, _>(&it.by_ref());
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs b/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs
new file mode 100644
index 000000000..b67853587
--- /dev/null
+++ b/src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs
@@ -0,0 +1,16 @@
+// Helper for test issue-18048, which tests associated types in a
+// cross-crate scenario.
+
+#![crate_type="lib"]
+
+pub trait Bar: Sized {
+ type T;
+
+ fn get(x: Option<Self>) -> <Self as Bar>::T;
+}
+
+impl Bar for isize {
+ type T = usize;
+
+ fn get(_: Option<isize>) -> usize { 22 }
+}
diff --git a/src/test/ui/associated-types/bound-lifetime-constrained.clause.stderr b/src/test/ui/associated-types/bound-lifetime-constrained.clause.stderr
new file mode 100644
index 000000000..f089f27f0
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-constrained.clause.stderr
@@ -0,0 +1,15 @@
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-constrained.rs:38:63
+ |
+LL | fn clause1<T>() where T: for<'a> Fn(<() as Foo<'a>>::Item) -> &'a i32 {
+ | ^^^^^^^
+
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-constrained.rs:43:42
+ |
+LL | fn clause2<T>() where T: for<'a> Fn() -> <() as Foo<'a>>::Item {
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/src/test/ui/associated-types/bound-lifetime-constrained.func.stderr b/src/test/ui/associated-types/bound-lifetime-constrained.func.stderr
new file mode 100644
index 000000000..88d15a171
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-constrained.func.stderr
@@ -0,0 +1,15 @@
+error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
+ --> $DIR/bound-lifetime-constrained.rs:16:50
+ |
+LL | fn func1(_: for<'a> fn(<() as Foo<'a>>::Item) -> &'a i32) {
+ | ^^^^^^^
+
+error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
+ --> $DIR/bound-lifetime-constrained.rs:23:29
+ |
+LL | fn func2(_: for<'a> fn() -> <() as Foo<'a>>::Item) {
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0581`.
diff --git a/src/test/ui/associated-types/bound-lifetime-constrained.object.stderr b/src/test/ui/associated-types/bound-lifetime-constrained.object.stderr
new file mode 100644
index 000000000..36fa06cce
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-constrained.object.stderr
@@ -0,0 +1,15 @@
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-constrained.rs:28:60
+ |
+LL | fn object1(_: Box<dyn for<'a> Fn(<() as Foo<'a>>::Item) -> &'a i32>) {
+ | ^^^^^^^
+
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-constrained.rs:33:39
+ |
+LL | fn object2(_: Box<dyn for<'a> Fn() -> <() as Foo<'a>>::Item>) {
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/src/test/ui/associated-types/bound-lifetime-constrained.rs b/src/test/ui/associated-types/bound-lifetime-constrained.rs
new file mode 100644
index 000000000..4e6754c86
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-constrained.rs
@@ -0,0 +1,48 @@
+// revisions: func object clause
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+
+trait Foo<'a> {
+ type Item;
+}
+
+impl<'a> Foo<'a> for() {
+ type Item = ();
+}
+
+// Check that appearing in a projection input in the argument is not enough:
+#[cfg(func)]
+fn func1(_: for<'a> fn(<() as Foo<'a>>::Item) -> &'a i32) {
+ //[func]~^ ERROR E0581
+}
+
+// Check that appearing in a projection input in the return still
+// causes an error:
+#[cfg(func)]
+fn func2(_: for<'a> fn() -> <() as Foo<'a>>::Item) {
+ //[func]~^ ERROR E0581
+}
+
+#[cfg(object)]
+fn object1(_: Box<dyn for<'a> Fn(<() as Foo<'a>>::Item) -> &'a i32>) {
+ //[object]~^ ERROR E0582
+}
+
+#[cfg(object)]
+fn object2(_: Box<dyn for<'a> Fn() -> <() as Foo<'a>>::Item>) {
+ //[object]~^ ERROR E0582
+}
+
+#[cfg(clause)]
+fn clause1<T>() where T: for<'a> Fn(<() as Foo<'a>>::Item) -> &'a i32 {
+ //[clause]~^ ERROR `Output` references lifetime `'a`
+}
+
+#[cfg(clause)]
+fn clause2<T>() where T: for<'a> Fn() -> <() as Foo<'a>>::Item {
+ //[clause]~^ ERROR `Output` references lifetime `'a`
+}
+
+#[rustc_error]
+fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.angle.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.angle.stderr
new file mode 100644
index 000000000..54f4bb907
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.angle.stderr
@@ -0,0 +1,27 @@
+error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:12:25
+ |
+LL | fn angle<T: for<'a> Foo<Item=&'a i32>>() {
+ | ^^^^^^^^^^^^
+
+error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:17:37
+ |
+LL | fn angle1<T>() where T: for<'a> Foo<Item=&'a i32> {
+ | ^^^^^^^^^^^^
+
+error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:22:37
+ |
+LL | fn angle2<T>() where for<'a> T: Foo<Item=&'a i32> {
+ | ^^^^^^^^^^^^
+
+error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:27:31
+ |
+LL | fn angle3(_: &dyn for<'a> Foo<Item=&'a i32>) {
+ | ^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr
new file mode 100644
index 000000000..4de4afb6e
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/bound-lifetime-in-binding-only.rs:52:23
+ |
+LL | fn elision<T: Fn() -> &i32>() {
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn elision<T: Fn() -> &'static i32>() {
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
new file mode 100644
index 000000000..b709fae5a
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/bound-lifetime-in-binding-only.rs:71:1
+ |
+LL | fn main() { }
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.paren.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.paren.stderr
new file mode 100644
index 000000000..74bc84c22
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.paren.stderr
@@ -0,0 +1,27 @@
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:32:29
+ |
+LL | fn paren<T: for<'a> Fn() -> &'a i32>() {
+ | ^^^^^^^
+
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:37:41
+ |
+LL | fn paren1<T>() where T: for<'a> Fn() -> &'a i32 {
+ | ^^^^^^^
+
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:42:41
+ |
+LL | fn paren2<T>() where for<'a> T: Fn() -> &'a i32 {
+ | ^^^^^^^
+
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+ --> $DIR/bound-lifetime-in-binding-only.rs:47:35
+ |
+LL | fn paren3(_: &dyn for<'a> Fn() -> &'a i32) {
+ | ^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs b/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs
new file mode 100644
index 000000000..e714457ef
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.rs
@@ -0,0 +1,71 @@
+// revisions: angle paren ok elision
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+#![feature(unboxed_closures)]
+
+trait Foo {
+ type Item;
+}
+
+#[cfg(angle)]
+fn angle<T: for<'a> Foo<Item=&'a i32>>() {
+ //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a`
+}
+
+#[cfg(angle)]
+fn angle1<T>() where T: for<'a> Foo<Item=&'a i32> {
+ //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a`
+}
+
+#[cfg(angle)]
+fn angle2<T>() where for<'a> T: Foo<Item=&'a i32> {
+ //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a`
+}
+
+#[cfg(angle)]
+fn angle3(_: &dyn for<'a> Foo<Item=&'a i32>) {
+ //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a`
+}
+
+#[cfg(paren)]
+fn paren<T: for<'a> Fn() -> &'a i32>() {
+ //[paren]~^ ERROR binding for associated type `Output` references lifetime `'a`
+}
+
+#[cfg(paren)]
+fn paren1<T>() where T: for<'a> Fn() -> &'a i32 {
+ //[paren]~^ ERROR binding for associated type `Output` references lifetime `'a`
+}
+
+#[cfg(paren)]
+fn paren2<T>() where for<'a> T: Fn() -> &'a i32 {
+ //[paren]~^ ERROR binding for associated type `Output` references lifetime `'a`
+}
+
+#[cfg(paren)]
+fn paren3(_: &dyn for<'a> Fn() -> &'a i32) {
+ //[paren]~^ ERROR binding for associated type `Output` references lifetime `'a`
+}
+
+#[cfg(elision)]
+fn elision<T: Fn() -> &i32>() {
+ //[elision]~^ ERROR E0106
+}
+
+struct Parameterized<'a> { x: &'a str }
+
+#[cfg(ok)]
+fn ok1<T: for<'a> Fn(&Parameterized<'a>) -> &'a i32>() {
+}
+
+#[cfg(ok)]
+fn ok2<T: for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>>() {
+}
+
+#[cfg(ok)]
+fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
+}
+
+#[rustc_error]
+fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr
new file mode 100644
index 000000000..7753d1865
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/bound-lifetime-in-return-only.rs:34:23
+ |
+LL | fn elision(_: fn() -> &i32) {
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn elision(_: fn() -> &'static i32) {
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.local.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.local.stderr
new file mode 100644
index 000000000..788cf667c
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.local.stderr
@@ -0,0 +1,9 @@
+error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
+ --> $DIR/bound-lifetime-in-return-only.rs:23:28
+ |
+LL | let _: for<'a> fn() -> &'a i32 = loop { };
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0581`.
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
new file mode 100644
index 000000000..1c0d3ac10
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
@@ -0,0 +1,8 @@
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/bound-lifetime-in-return-only.rs:49:1
+ |
+LL | fn main() { }
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.rs b/src/test/ui/associated-types/bound-lifetime-in-return-only.rs
new file mode 100644
index 000000000..a60ccb6c4
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.rs
@@ -0,0 +1,49 @@
+// revisions: sig local structure ok elision
+
+#![allow(dead_code)]
+#![feature(rustc_attrs)]
+#![feature(unboxed_closures)]
+
+trait Foo {
+ type Item;
+}
+
+#[cfg(sig)]
+fn sig1(_: for<'a> fn() -> &'a i32) {
+ //[sig]~^ ERROR return type references lifetime `'a`
+}
+
+#[cfg(sig)]
+fn sig2(_: for<'a, 'b> fn(&'b i32) -> &'a i32) {
+ //[sig]~^ ERROR return type references lifetime `'a`
+}
+
+#[cfg(local)]
+fn local1() {
+ let _: for<'a> fn() -> &'a i32 = loop { };
+ //[local]~^ ERROR return type references lifetime `'a`
+}
+
+#[cfg(structure)]
+struct Struct1 {
+ x: for<'a> fn() -> &'a i32
+ //[structure]~^ ERROR return type references lifetime `'a`
+}
+
+#[cfg(elision)]
+fn elision(_: fn() -> &i32) {
+ //[elision]~^ ERROR E0106
+}
+
+struct Parameterized<'a> { x: &'a str }
+
+#[cfg(ok)]
+fn ok1(_: &dyn for<'a> Fn(&Parameterized<'a>) -> &'a i32) {
+}
+
+#[cfg(ok)]
+fn ok2(_: &dyn for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>) {
+}
+
+#[rustc_error]
+fn main() { } //[ok]~ ERROR fatal error triggered by #[rustc_error]
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.sig.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.sig.stderr
new file mode 100644
index 000000000..64dad4619
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.sig.stderr
@@ -0,0 +1,15 @@
+error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
+ --> $DIR/bound-lifetime-in-return-only.rs:12:28
+ |
+LL | fn sig1(_: for<'a> fn() -> &'a i32) {
+ | ^^^^^^^
+
+error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
+ --> $DIR/bound-lifetime-in-return-only.rs:17:39
+ |
+LL | fn sig2(_: for<'a, 'b> fn(&'b i32) -> &'a i32) {
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0581`.
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.structure.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.structure.stderr
new file mode 100644
index 000000000..f7833500d
--- /dev/null
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.structure.stderr
@@ -0,0 +1,9 @@
+error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
+ --> $DIR/bound-lifetime-in-return-only.rs:29:24
+ |
+LL | x: for<'a> fn() -> &'a i32
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0581`.
diff --git a/src/test/ui/associated-types/cache/chrono-scan.rs b/src/test/ui/associated-types/cache/chrono-scan.rs
new file mode 100644
index 000000000..964ddc9b6
--- /dev/null
+++ b/src/test/ui/associated-types/cache/chrono-scan.rs
@@ -0,0 +1,30 @@
+// check-pass
+
+#![allow(deprecated)]
+
+pub type ParseResult<T> = Result<T, ()>;
+
+pub enum Item<'a> {
+ Literal(&'a str)
+}
+
+pub fn colon_or_space(s: &str) -> ParseResult<&str> {
+ unimplemented!()
+}
+
+pub fn timezone_offset_zulu<F>(s: &str, colon: F) -> ParseResult<(&str, i32)>
+ where F: FnMut(&str) -> ParseResult<&str> {
+ unimplemented!()
+}
+
+pub fn parse<'a, I>(mut s: &str, items: I) -> ParseResult<()>
+ where I: Iterator<Item=Item<'a>> {
+ macro_rules! try_consume {
+ ($e:expr) => ({ let (s_, v) = try!($e); s = s_; v })
+ }
+ let offset = try_consume!(timezone_offset_zulu(s.trim_start(), colon_or_space));
+ let offset = try_consume!(timezone_offset_zulu(s.trim_start(), colon_or_space));
+ Ok(())
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/cache/elision.rs b/src/test/ui/associated-types/cache/elision.rs
new file mode 100644
index 000000000..b3e1ec8ad
--- /dev/null
+++ b/src/test/ui/associated-types/cache/elision.rs
@@ -0,0 +1,23 @@
+// Check that you are allowed to implement using elision but write
+// trait without elision (a bug in this cropped up during
+// bootstrapping, so this is a regression test).
+
+// check-pass
+
+pub struct SplitWhitespace<'a> {
+ x: &'a u8
+}
+
+pub trait UnicodeStr {
+ fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
+}
+
+impl UnicodeStr for str {
+ #[inline]
+ fn split_whitespace(&self) -> SplitWhitespace {
+ unimplemented!()
+ }
+}
+
+
+fn main() { }
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
new file mode 100644
index 000000000..2ecee1341
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
@@ -0,0 +1,30 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:46:4
+ |
+LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:46:4
+ |
+LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
new file mode 100644
index 000000000..f1ea6627a
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
@@ -0,0 +1,50 @@
+#![feature(unboxed_closures)]
+
+// Test for projection cache. We should be able to project distinct
+// lifetimes from `foo` as we reinstantiate it multiple times, but not
+// if we do it just once. In this variant, the region `'a` is used in
+// an contravariant position, which affects the results.
+
+// revisions: ok oneuse transmute krisskross
+//[ok] check-pass
+//[oneuse] check-pass
+
+#![allow(dead_code, unused_variables)]
+
+fn foo<'a>() -> &'a u32 { loop { } }
+
+fn bar<T>(t: T, x: T::Output) -> T::Output
+ where T: FnOnce<()>
+{
+ t()
+}
+
+#[cfg(ok)] // two instantiations: OK
+fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ let a = bar(foo, x);
+ let b = bar(foo, y);
+ (a, b)
+}
+
+#[cfg(oneuse)] // one instantiation: OK (surprisingly)
+fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ let f /* : fn() -> &'static u32 */ = foo; // <-- inferred type annotated
+ let a = bar(f, x); // this is considered ok because fn args are contravariant...
+ let b = bar(f, y); // ...and hence we infer T to distinct values in each call.
+ (a, b)
+}
+
+#[cfg(transmute)] // one instantiations: BAD
+fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+ bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
+}
+
+#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
+fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ let a = bar(foo, y);
+ let b = bar(foo, x);
+ (a, b) //[krisskross]~ ERROR lifetime may not live long enough
+ //[krisskross]~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
new file mode 100644
index 000000000..6d8ab2c3f
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:39:4
+ |
+LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | bar(foo, x)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
new file mode 100644
index 000000000..ada12c7ee
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
@@ -0,0 +1,36 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:59:5
+ |
+LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:59:5
+ |
+LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
new file mode 100644
index 000000000..cc1560162
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
@@ -0,0 +1,36 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:40:13
+ |
+LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
+LL | let a = bar(f, x);
+ | ^^^^^^^^^ argument requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:40:13
+ |
+LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
+LL | let a = bar(f, x);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+ = note: requirement occurs because of a function pointer to `foo`
+ = note: the function `foo` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
new file mode 100644
index 000000000..1075fd6e0
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
@@ -0,0 +1,64 @@
+#![feature(unboxed_closures)]
+// Test for projection cache. We should be able to project distinct
+// lifetimes from `foo` as we reinstantiate it multiple times, but not
+// if we do it just once. In this variant, the region `'a` is used in
+// an invariant position, which affects the results.
+
+// revisions: ok oneuse transmute krisskross
+//[ok] check-pass
+
+#![allow(dead_code, unused_variables)]
+
+use std::marker::PhantomData;
+
+struct Type<'a> {
+ // Invariant
+ data: PhantomData<fn(&'a u32) -> &'a u32>,
+}
+
+fn foo<'a>() -> Type<'a> {
+ loop {}
+}
+
+fn bar<T>(t: T, x: T::Output) -> T::Output
+where
+ T: FnOnce<()>,
+{
+ t()
+}
+
+#[cfg(ok)] // two instantiations: OK
+fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ let a = bar(foo, x);
+ let b = bar(foo, y);
+ (a, b)
+}
+
+#[cfg(oneuse)] // one instantiation: BAD
+fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ let f = foo; // <-- No consistent type can be inferred for `f` here.
+ let a = bar(f, x);
+ //[oneuse]~^ ERROR lifetime may not live long enough
+ //[oneuse]~| ERROR lifetime may not live long enough
+ let b = bar(f, y);
+ (a, b)
+}
+
+#[cfg(transmute)] // one instantiations: BAD
+fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
+ // Cannot instantiate `foo` with any lifetime other than `'a`,
+ // since it is provided as input.
+
+ bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
+}
+
+#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
+fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ let a = bar(foo, y);
+ let b = bar(foo, x);
+ (a, b)
+ //[krisskross]~^ ERROR lifetime may not live long enough
+ //[krisskross]~| ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
new file mode 100644
index 000000000..b64cb2c3d
--- /dev/null
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:52:5
+ |
+LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
+ | -- lifetime `'a` defined here
+...
+LL | bar(foo, x)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ |
+ = note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Type<'a>` is invariant over the parameter `'a`
+ = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/default-associated-types.rs b/src/test/ui/associated-types/default-associated-types.rs
new file mode 100644
index 000000000..aae70bffa
--- /dev/null
+++ b/src/test/ui/associated-types/default-associated-types.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![feature(associated_type_defaults)]
+
+trait Foo<T: Default + ToString> {
+ type Out: Default + ToString = T;
+}
+
+impl Foo<u32> for () {
+}
+
+impl Foo<u64> for () {
+ type Out = bool;
+}
+
+fn main() {
+ assert_eq!(
+ <() as Foo<u32>>::Out::default().to_string(),
+ "0");
+ assert_eq!(
+ <() as Foo<u64>>::Out::default().to_string(),
+ "false");
+}
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-1.rs b/src/test/ui/associated-types/defaults-cyclic-fail-1.rs
new file mode 100644
index 000000000..61ef01323
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-1.rs
@@ -0,0 +1,40 @@
+#![feature(associated_type_defaults)]
+
+// Having a cycle in assoc. type defaults is okay...
+trait Tr {
+ type A = Self::B;
+ type B = Self::A;
+}
+
+impl Tr for () {}
+
+impl Tr for u8 {
+ type A = u8;
+}
+
+impl Tr for u16 {
+ type B = ();
+}
+
+impl Tr for u32 {
+ type A = ();
+ type B = u8;
+}
+
+// ...but not in an impl that redefines one of the types.
+impl Tr for bool {
+ type A = Box<Self::B>;
+ //~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
+}
+// (the error is shown twice for some reason)
+
+impl Tr for usize {
+ type B = &'static Self::A;
+ //~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
+}
+
+fn main() {
+ // We don't check that the types project correctly because the cycle errors stop compilation
+ // before `main` is type-checked.
+ // `defaults-cyclic-pass-1.rs` does this.
+}
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr b/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
new file mode 100644
index 000000000..008eddcb2
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-1.stderr
@@ -0,0 +1,15 @@
+error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
+ --> $DIR/defaults-cyclic-fail-1.rs:26:14
+ |
+LL | type A = Box<Self::B>;
+ | ^^^^^^^^^^^^
+
+error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
+ --> $DIR/defaults-cyclic-fail-1.rs:32:14
+ |
+LL | type B = &'static Self::A;
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-2.rs b/src/test/ui/associated-types/defaults-cyclic-fail-2.rs
new file mode 100644
index 000000000..e91c9f2d2
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-2.rs
@@ -0,0 +1,41 @@
+#![feature(associated_type_defaults)]
+
+// A more complex version of `defaults-cyclic-fail-1.rs`, with non-trivial defaults.
+
+// Having a cycle in assoc. type defaults is okay...
+trait Tr {
+ type A = Vec<Self::B>;
+ type B = Box<Self::A>;
+}
+
+impl Tr for () {}
+
+impl Tr for u8 {
+ type A = u8;
+}
+
+impl Tr for u16 {
+ type B = ();
+}
+
+impl Tr for u32 {
+ type A = ();
+ type B = u8;
+}
+
+impl Tr for bool {
+ type A = Box<Self::B>;
+ //~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
+}
+// (the error is shown twice for some reason)
+
+impl Tr for usize {
+ type B = &'static Self::A;
+ //~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
+}
+
+fn main() {
+ // We don't check that the types project correctly because the cycle errors stop compilation
+ // before `main` is type-checked.
+ // `defaults-cyclic-pass-2.rs` does this.
+}
diff --git a/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr b/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
new file mode 100644
index 000000000..d0fbab077
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-cyclic-fail-2.stderr
@@ -0,0 +1,15 @@
+error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
+ --> $DIR/defaults-cyclic-fail-2.rs:27:14
+ |
+LL | type A = Box<Self::B>;
+ | ^^^^^^^^^^^^
+
+error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
+ --> $DIR/defaults-cyclic-fail-2.rs:33:14
+ |
+LL | type B = &'static Self::A;
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/defaults-cyclic-pass-1.rs b/src/test/ui/associated-types/defaults-cyclic-pass-1.rs
new file mode 100644
index 000000000..97c6e5bad
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-cyclic-pass-1.rs
@@ -0,0 +1,56 @@
+// check-pass
+
+#![feature(associated_type_defaults)]
+
+// Having a cycle in assoc. type defaults is okay, as long as there's no impl
+// that retains it.
+trait Tr {
+ type A = Self::B;
+ type B = Self::A;
+
+ fn f();
+}
+
+// An impl has to break the cycle to be accepted.
+impl Tr for u8 {
+ type A = u8;
+
+ fn f() {
+ // Check that the type propagates as expected (seen from inside the impl)
+ let _: Self::A = 0u8;
+ let _: Self::B = 0u8;
+ }
+}
+
+impl Tr for String {
+ type B = ();
+
+ fn f() {
+ // Check that the type propagates as expected (seen from inside the impl)
+ let _: Self::A = ();
+ let _: Self::B = ();
+ }
+}
+
+impl Tr for () {
+ type A = Vec<()>;
+ type B = u8;
+
+ fn f() {
+ // Check that the type propagates as expected (seen from inside the impl)
+ let _: Self::A = Vec::<()>::new();
+ let _: Self::B = 0u8;
+ }
+}
+
+fn main() {
+ // Check that both impls now have the right types (seen from outside the impls)
+ let _: <u8 as Tr>::A = 0u8;
+ let _: <u8 as Tr>::B = 0u8;
+
+ let _: <String as Tr>::A = ();
+ let _: <String as Tr>::B = ();
+
+ let _: <() as Tr>::A = Vec::<()>::new();
+ let _: <() as Tr>::B = 0u8;
+}
diff --git a/src/test/ui/associated-types/defaults-cyclic-pass-2.rs b/src/test/ui/associated-types/defaults-cyclic-pass-2.rs
new file mode 100644
index 000000000..69315a022
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-cyclic-pass-2.rs
@@ -0,0 +1,56 @@
+// check-pass
+
+#![feature(associated_type_defaults)]
+
+// Having a cycle in assoc. type defaults is okay, as long as there's no impl
+// that retains it.
+trait Tr {
+ type A = Vec<Self::B>;
+ type B = Box<Self::A>;
+
+ fn f();
+}
+
+// An impl has to break the cycle to be accepted.
+impl Tr for u8 {
+ type A = u8;
+
+ fn f() {
+ // Check that the type propagates as expected (seen from inside the impl)
+ let _: Self::A = 0u8;
+ let _: Self::B = Box::new(0u8);
+ }
+}
+
+impl Tr for String {
+ type B = ();
+
+ fn f() {
+ // Check that the type propagates as expected (seen from inside the impl)
+ let _: Self::A = Vec::<()>::new();
+ let _: Self::B = ();
+ }
+}
+
+impl Tr for () {
+ type A = Vec<()>;
+ type B = u8;
+
+ fn f() {
+ // Check that the type propagates as expected (seen from inside the impl)
+ let _: Self::A = Vec::<()>::new();
+ let _: Self::B = 0u8;
+ }
+}
+
+fn main() {
+ // Check that both impls now have the right types (seen from outside the impls)
+ let _: <u8 as Tr>::A = 0u8;
+ let _: <u8 as Tr>::B = Box::new(0u8);
+
+ let _: <String as Tr>::A = Vec::<()>::new();
+ let _: <String as Tr>::B = ();
+
+ let _: <() as Tr>::A = Vec::<()>::new();
+ let _: <() as Tr>::B = 0u8;
+}
diff --git a/src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs b/src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs
new file mode 100644
index 000000000..a3bfcd8ef
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+#![feature(associated_type_defaults)]
+
+trait Tr {
+ type Item = u8;
+ type Container = Vec<Self::Item>;
+}
+
+impl Tr for () {}
+
+impl Tr for u16 {
+ type Item = u16;
+}
+
+impl Tr for String {
+ type Container = String;
+}
+
+impl Tr for usize {
+ type Item = u32;
+ type Container = Vec<()>;
+}
+
+fn main() {
+ let _container: <() as Tr>::Container = Vec::<u8>::new();
+ let _item: <() as Tr>::Item = 0u8;
+
+ let _container: <u16 as Tr>::Container = Vec::<u16>::new();
+ let _item: <u16 as Tr>::Item = 0u16;
+
+ let _container: <String as Tr>::Container = String::new();
+ let _item: <String as Tr>::Item = 0u8;
+
+ let _container: <usize as Tr>::Container = Vec::<()>::new();
+ let _item: <usize as Tr>::Item = 0u32;
+}
diff --git a/src/test/ui/associated-types/defaults-in-other-trait-items.rs b/src/test/ui/associated-types/defaults-in-other-trait-items.rs
new file mode 100644
index 000000000..505751969
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-in-other-trait-items.rs
@@ -0,0 +1,47 @@
+#![feature(associated_type_defaults)]
+
+// Associated type defaults may not be assumed inside the trait defining them.
+// ie. they only resolve to `<Self as Tr>::A`, not the actual type `()`
+trait Tr {
+ type A = (); //~ NOTE associated type defaults can't be assumed inside the trait defining them
+
+ fn f(p: Self::A) {
+ let () = p;
+ //~^ ERROR mismatched types
+ //~| NOTE expected associated type, found `()`
+ //~| NOTE expected associated type `<Self as Tr>::A`
+ //~| NOTE this expression has type `<Self as Tr>::A`
+ }
+}
+
+// An impl that doesn't override the type *can* assume the default.
+impl Tr for () {
+ fn f(p: Self::A) {
+ let () = p;
+ }
+}
+
+impl Tr for u8 {
+ type A = ();
+
+ fn f(p: Self::A) {
+ let () = p;
+ }
+}
+
+trait AssocConst {
+ type Ty = u8; //~ NOTE associated type defaults can't be assumed inside the trait defining them
+
+ // Assoc. consts also cannot assume that default types hold
+ const C: Self::Ty = 0u8;
+ //~^ ERROR mismatched types
+ //~| NOTE expected associated type, found `u8`
+ //~| NOTE expected associated type `<Self as AssocConst>::Ty`
+}
+
+// An impl can, however
+impl AssocConst for () {
+ const C: Self::Ty = 0u8;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/defaults-in-other-trait-items.stderr b/src/test/ui/associated-types/defaults-in-other-trait-items.stderr
new file mode 100644
index 000000000..71d421926
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-in-other-trait-items.stderr
@@ -0,0 +1,29 @@
+error[E0308]: mismatched types
+ --> $DIR/defaults-in-other-trait-items.rs:9:13
+ |
+LL | type A = ();
+ | ------------ associated type defaults can't be assumed inside the trait defining them
+...
+LL | let () = p;
+ | ^^ - this expression has type `<Self as Tr>::A`
+ | |
+ | expected associated type, found `()`
+ |
+ = note: expected associated type `<Self as Tr>::A`
+ found unit type `()`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-in-other-trait-items.rs:36:25
+ |
+LL | type Ty = u8;
+ | ------------- associated type defaults can't be assumed inside the trait defining them
+...
+LL | const C: Self::Ty = 0u8;
+ | ^^^ expected associated type, found `u8`
+ |
+ = note: expected associated type `<Self as AssocConst>::Ty`
+ found type `u8`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/defaults-mixed.rs b/src/test/ui/associated-types/defaults-mixed.rs
new file mode 100644
index 000000000..c91b8de39
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-mixed.rs
@@ -0,0 +1,34 @@
+#![feature(associated_type_defaults)]
+
+// Tests that a trait with one defaulted and one non-defaulted assoc. type behaves properly.
+
+trait Trait {
+ type Foo = u8;
+ type Bar;
+}
+
+// `Bar` must be specified
+impl Trait for () {}
+//~^ error: not all trait items implemented, missing: `Bar`
+
+impl Trait for bool {
+//~^ error: not all trait items implemented, missing: `Bar`
+ type Foo = ();
+}
+
+impl Trait for u8 {
+ type Bar = ();
+}
+
+impl Trait for u16 {
+ type Foo = String;
+ type Bar = bool;
+}
+
+fn main() {
+ let _: <u8 as Trait>::Foo = 0u8;
+ let _: <u8 as Trait>::Bar = ();
+
+ let _: <u16 as Trait>::Foo = String::new();
+ let _: <u16 as Trait>::Bar = true;
+}
diff --git a/src/test/ui/associated-types/defaults-mixed.stderr b/src/test/ui/associated-types/defaults-mixed.stderr
new file mode 100644
index 000000000..0f4a6968c
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-mixed.stderr
@@ -0,0 +1,21 @@
+error[E0046]: not all trait items implemented, missing: `Bar`
+ --> $DIR/defaults-mixed.rs:11:1
+ |
+LL | type Bar;
+ | -------- `Bar` from trait
+...
+LL | impl Trait for () {}
+ | ^^^^^^^^^^^^^^^^^ missing `Bar` in implementation
+
+error[E0046]: not all trait items implemented, missing: `Bar`
+ --> $DIR/defaults-mixed.rs:14:1
+ |
+LL | type Bar;
+ | -------- `Bar` from trait
+...
+LL | impl Trait for bool {
+ | ^^^^^^^^^^^^^^^^^^^ missing `Bar` in implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/associated-types/defaults-specialization.rs b/src/test/ui/associated-types/defaults-specialization.rs
new file mode 100644
index 000000000..553705b2a
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-specialization.rs
@@ -0,0 +1,96 @@
+//! Tests the interaction of associated type defaults and specialization.
+
+#![feature(associated_type_defaults, specialization)]
+//~^ WARN the feature `specialization` is incomplete
+
+trait Tr {
+ type Ty = u8;
+
+ fn make() -> Self::Ty {
+ 0u8
+ //~^ error: mismatched types
+ }
+}
+
+struct A<T>(T);
+// In a `default impl`, assoc. types are defaulted as well,
+// so their values can't be assumed.
+default impl<T> Tr for A<T> {
+ fn make() -> u8 { 0 }
+ //~^ ERROR method `make` has an incompatible type for trait
+}
+
+struct A2<T>(T);
+// ...same, but in the method body
+default impl<T> Tr for A2<T> {
+ fn make() -> Self::Ty { 0u8 }
+ //~^ ERROR mismatched types
+}
+
+struct B<T>(T);
+// Explicitly defaulting the type does the same.
+impl<T> Tr for B<T> {
+ default type Ty = bool;
+
+ fn make() -> bool { true }
+ //~^ ERROR method `make` has an incompatible type for trait
+}
+
+struct B2<T>(T);
+// ...same, but in the method body
+impl<T> Tr for B2<T> {
+ default type Ty = bool;
+
+ fn make() -> Self::Ty { true }
+ //~^ ERROR mismatched types
+}
+
+struct C<T>(T);
+// Only the method is defaulted, so this is fine.
+impl<T> Tr for C<T> {
+ type Ty = bool;
+
+ default fn make() -> bool { true }
+}
+
+// Defaulted method *can* assume the type, if the default is kept.
+struct D<T>(T);
+impl<T> Tr for D<T> {
+ default fn make() -> u8 { 0 }
+}
+
+impl Tr for D<bool> {
+ fn make() -> u8 { 255 }
+}
+
+struct E<T>(T);
+impl<T> Tr for E<T> {
+ default type Ty = bool;
+ default fn make() -> Self::Ty { panic!(); }
+}
+
+// This impl specializes and sets `Ty`, it can rely on `Ty=String`.
+impl Tr for E<bool> {
+ type Ty = String;
+
+ fn make() -> String { String::new() }
+}
+
+fn main() {
+ // Test that we can assume the right set of assoc. types from outside the impl
+
+ // This is a `default impl`, which does *not* mean that `A`/`A2` actually implement the trait.
+ // cf. https://github.com/rust-lang/rust/issues/48515
+ //let _: <A<()> as Tr>::Ty = 0u8;
+ //let _: <A2<()> as Tr>::Ty = 0u8;
+
+ let _: <B<()> as Tr>::Ty = 0u8; //~ error: mismatched types
+ let _: <B<()> as Tr>::Ty = true; //~ error: mismatched types
+ let _: <B2<()> as Tr>::Ty = 0u8; //~ error: mismatched types
+ let _: <B2<()> as Tr>::Ty = true; //~ error: mismatched types
+
+ let _: <C<()> as Tr>::Ty = true;
+
+ let _: <D<()> as Tr>::Ty = 0u8;
+ let _: <D<bool> as Tr>::Ty = 0u8;
+}
diff --git a/src/test/ui/associated-types/defaults-specialization.stderr b/src/test/ui/associated-types/defaults-specialization.stderr
new file mode 100644
index 000000000..2d61b2a64
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-specialization.stderr
@@ -0,0 +1,156 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+ --> $DIR/defaults-specialization.rs:3:38
+ |
+LL | #![feature(associated_type_defaults, specialization)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+ = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+ = help: consider using `min_specialization` instead, which is more stable and complete
+
+error[E0053]: method `make` has an incompatible type for trait
+ --> $DIR/defaults-specialization.rs:19:18
+ |
+LL | fn make() -> u8 { 0 }
+ | ^^
+ | |
+ | expected associated type, found `u8`
+ | help: change the output type to match the trait: `<A<T> as Tr>::Ty`
+ |
+note: type in trait
+ --> $DIR/defaults-specialization.rs:9:18
+ |
+LL | fn make() -> Self::Ty {
+ | ^^^^^^^^
+ = note: expected fn pointer `fn() -> <A<T> as Tr>::Ty`
+ found fn pointer `fn() -> u8`
+
+error[E0053]: method `make` has an incompatible type for trait
+ --> $DIR/defaults-specialization.rs:35:18
+ |
+LL | default type Ty = bool;
+ | ----------------------- expected this associated type
+LL |
+LL | fn make() -> bool { true }
+ | ^^^^
+ | |
+ | expected associated type, found `bool`
+ | help: change the output type to match the trait: `<B<T> as Tr>::Ty`
+ |
+note: type in trait
+ --> $DIR/defaults-specialization.rs:9:18
+ |
+LL | fn make() -> Self::Ty {
+ | ^^^^^^^^
+ = note: expected fn pointer `fn() -> <B<T> as Tr>::Ty`
+ found fn pointer `fn() -> bool`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:10:9
+ |
+LL | type Ty = u8;
+ | ------------- associated type defaults can't be assumed inside the trait defining them
+LL |
+LL | fn make() -> Self::Ty {
+ | -------- expected `<Self as Tr>::Ty` because of return type
+LL | 0u8
+ | ^^^ expected associated type, found `u8`
+ |
+ = note: expected associated type `<Self as Tr>::Ty`
+ found type `u8`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:26:29
+ |
+LL | fn make() -> Self::Ty { 0u8 }
+ | -------- ^^^ expected associated type, found `u8`
+ | |
+ | expected `<A2<T> as Tr>::Ty` because of return type
+ |
+ = note: expected associated type `<A2<T> as Tr>::Ty`
+ found type `u8`
+ = help: consider constraining the associated type `<A2<T> as Tr>::Ty` to `u8` or calling a method that returns `<A2<T> as Tr>::Ty`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:44:29
+ |
+LL | default type Ty = bool;
+ | ----------------------- expected this associated type
+LL |
+LL | fn make() -> Self::Ty { true }
+ | -------- ^^^^ expected associated type, found `bool`
+ | |
+ | expected `<B2<T> as Tr>::Ty` because of return type
+ |
+ = note: expected associated type `<B2<T> as Tr>::Ty`
+ found type `bool`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:87:32
+ |
+LL | let _: <B<()> as Tr>::Ty = 0u8;
+ | ----------------- ^^^ expected associated type, found `u8`
+ | |
+ | expected due to this
+ |
+ = note: expected associated type `<B<()> as Tr>::Ty`
+ found type `u8`
+help: a method is available that returns `<B<()> as Tr>::Ty`
+ --> $DIR/defaults-specialization.rs:9:5
+ |
+LL | fn make() -> Self::Ty {
+ | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:88:32
+ |
+LL | let _: <B<()> as Tr>::Ty = true;
+ | ----------------- ^^^^ expected associated type, found `bool`
+ | |
+ | expected due to this
+ |
+ = note: expected associated type `<B<()> as Tr>::Ty`
+ found type `bool`
+help: a method is available that returns `<B<()> as Tr>::Ty`
+ --> $DIR/defaults-specialization.rs:9:5
+ |
+LL | fn make() -> Self::Ty {
+ | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:89:33
+ |
+LL | let _: <B2<()> as Tr>::Ty = 0u8;
+ | ------------------ ^^^ expected associated type, found `u8`
+ | |
+ | expected due to this
+ |
+ = note: expected associated type `<B2<()> as Tr>::Ty`
+ found type `u8`
+help: a method is available that returns `<B2<()> as Tr>::Ty`
+ --> $DIR/defaults-specialization.rs:9:5
+ |
+LL | fn make() -> Self::Ty {
+ | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make`
+
+error[E0308]: mismatched types
+ --> $DIR/defaults-specialization.rs:90:33
+ |
+LL | let _: <B2<()> as Tr>::Ty = true;
+ | ------------------ ^^^^ expected associated type, found `bool`
+ | |
+ | expected due to this
+ |
+ = note: expected associated type `<B2<()> as Tr>::Ty`
+ found type `bool`
+help: a method is available that returns `<B2<()> as Tr>::Ty`
+ --> $DIR/defaults-specialization.rs:9:5
+ |
+LL | fn make() -> Self::Ty {
+ | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make`
+
+error: aborting due to 9 previous errors; 1 warning emitted
+
+Some errors have detailed explanations: E0053, E0308.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/src/test/ui/associated-types/defaults-suitability.rs b/src/test/ui/associated-types/defaults-suitability.rs
new file mode 100644
index 000000000..504c957d9
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-suitability.rs
@@ -0,0 +1,101 @@
+//! Checks that associated type defaults are properly validated.
+//!
+//! This means:
+//! * Default types are checked against where clauses on the assoc. type
+//! (eg. `type Assoc: Clone = NotClone`)
+
+#![feature(associated_type_defaults)]
+
+struct NotClone;
+
+// Assoc. type bounds must hold for the default type
+trait Tr {
+ type Ty: Clone = NotClone;
+ //~^ ERROR the trait bound `NotClone: Clone` is not satisfied
+}
+
+// Where-clauses defined on the trait must also be considered
+trait Tr2
+where
+ Self::Ty: Clone,
+{
+ type Ty = NotClone;
+ //~^ ERROR the trait bound `NotClone: Clone` is not satisfied
+}
+
+// Involved type parameters must fulfill all bounds required by defaults that mention them
+trait Foo<T> {
+ type Bar: Clone = Vec<T>;
+ //~^ ERROR the trait bound `T: Clone` is not satisfied
+}
+
+trait Bar: Sized {
+ // `(): Foo<Self>` might hold for some possible impls but not all.
+ type Assoc: Foo<Self> = ();
+ //~^ ERROR the trait bound `(): Foo<Self>` is not satisfied
+}
+
+trait IsU8<T> {}
+impl<T> IsU8<u8> for T {}
+
+// Test that mentioning the assoc. type inside where clauses is not allowed
+trait C where
+ Vec<Self::Assoc>: Clone,
+ Self::Assoc: IsU8<Self::Assoc>,
+ bool: IsU8<Self::Assoc>,
+{
+ type Assoc = u8;
+}
+
+// Test that we get all expected errors if that default is unsuitable
+trait D where
+ Vec<Self::Assoc>: Clone,
+ Self::Assoc: IsU8<Self::Assoc>,
+ bool: IsU8<Self::Assoc>,
+{
+ type Assoc = NotClone;
+ //~^ ERROR the trait bound `NotClone: IsU8<NotClone>` is not satisfied
+}
+
+// Test behavior of the check when defaults refer to other defaults:
+
+// Shallow substitution rejects this trait since `Baz` isn't guaranteed to be
+// `Clone`.
+trait Foo2<T> {
+ type Bar: Clone = Vec<Self::Baz>;
+ //~^ ERROR the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
+ type Baz = T;
+}
+
+// Adding a `T: Clone` bound doesn't help since the requirement doesn't see `T`
+// because of the shallow substitution. If we did a deep substitution instead,
+// this would be accepted.
+trait Foo25<T: Clone> {
+ type Bar: Clone = Vec<Self::Baz>;
+ //~^ ERROR the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
+ type Baz = T;
+}
+
+// Adding the `Baz: Clone` bound isn't enough since the default is type
+// parameter `T`, which also might not be `Clone`.
+trait Foo3<T>
+where
+ Self::Bar: Clone,
+ Self::Baz: Clone,
+{
+ type Bar = Vec<Self::Baz>;
+ type Baz = T;
+ //~^ ERROR the trait bound `T: Clone` is not satisfied
+}
+
+// This one finally works, with `Clone` bounds on all assoc. types and the type
+// parameter.
+trait Foo4<T>
+where
+ T: Clone,
+{
+ type Bar: Clone = Vec<Self::Baz>;
+ type Baz: Clone = T;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/defaults-suitability.stderr b/src/test/ui/associated-types/defaults-suitability.stderr
new file mode 100644
index 000000000..43541c5df
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-suitability.stderr
@@ -0,0 +1,135 @@
+error[E0277]: the trait bound `NotClone: Clone` is not satisfied
+ --> $DIR/defaults-suitability.rs:13:22
+ |
+LL | type Ty: Clone = NotClone;
+ | ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
+ |
+note: required by a bound in `Tr::Ty`
+ --> $DIR/defaults-suitability.rs:13:14
+ |
+LL | type Ty: Clone = NotClone;
+ | ^^^^^ required by this bound in `Tr::Ty`
+help: consider annotating `NotClone` with `#[derive(Clone)]`
+ |
+LL | #[derive(Clone)]
+ |
+
+error[E0277]: the trait bound `NotClone: Clone` is not satisfied
+ --> $DIR/defaults-suitability.rs:22:15
+ |
+LL | type Ty = NotClone;
+ | ^^^^^^^^ the trait `Clone` is not implemented for `NotClone`
+ |
+note: required by a bound in `Tr2::Ty`
+ --> $DIR/defaults-suitability.rs:20:15
+ |
+LL | Self::Ty: Clone,
+ | ^^^^^ required by this bound in `Tr2::Ty`
+LL | {
+LL | type Ty = NotClone;
+ | -- required by a bound in this
+help: consider annotating `NotClone` with `#[derive(Clone)]`
+ |
+LL | #[derive(Clone)]
+ |
+
+error[E0277]: the trait bound `T: Clone` is not satisfied
+ --> $DIR/defaults-suitability.rs:28:23
+ |
+LL | type Bar: Clone = Vec<T>;
+ | ^^^^^^ the trait `Clone` is not implemented for `T`
+ |
+ = note: required because of the requirements on the impl of `Clone` for `Vec<T>`
+note: required by a bound in `Foo::Bar`
+ --> $DIR/defaults-suitability.rs:28:15
+ |
+LL | type Bar: Clone = Vec<T>;
+ | ^^^^^ required by this bound in `Foo::Bar`
+help: consider restricting type parameter `T`
+ |
+LL | trait Foo<T: std::clone::Clone> {
+ | +++++++++++++++++++
+
+error[E0277]: the trait bound `(): Foo<Self>` is not satisfied
+ --> $DIR/defaults-suitability.rs:34:29
+ |
+LL | type Assoc: Foo<Self> = ();
+ | ^^ the trait `Foo<Self>` is not implemented for `()`
+ |
+note: required by a bound in `Bar::Assoc`
+ --> $DIR/defaults-suitability.rs:34:17
+ |
+LL | type Assoc: Foo<Self> = ();
+ | ^^^^^^^^^ required by this bound in `Bar::Assoc`
+
+error[E0277]: the trait bound `NotClone: IsU8<NotClone>` is not satisfied
+ --> $DIR/defaults-suitability.rs:56:18
+ |
+LL | type Assoc = NotClone;
+ | ^^^^^^^^ the trait `IsU8<NotClone>` is not implemented for `NotClone`
+ |
+note: required by a bound in `D::Assoc`
+ --> $DIR/defaults-suitability.rs:53:18
+ |
+LL | Self::Assoc: IsU8<Self::Assoc>,
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc`
+...
+LL | type Assoc = NotClone;
+ | ----- required by a bound in this
+
+error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied
+ --> $DIR/defaults-suitability.rs:65:23
+ |
+LL | type Bar: Clone = Vec<Self::Baz>;
+ | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo2<T>>::Baz`
+ |
+ = note: required because of the requirements on the impl of `Clone` for `Vec<<Self as Foo2<T>>::Baz>`
+note: required by a bound in `Foo2::Bar`
+ --> $DIR/defaults-suitability.rs:65:15
+ |
+LL | type Bar: Clone = Vec<Self::Baz>;
+ | ^^^^^ required by this bound in `Foo2::Bar`
+help: consider further restricting the associated type
+ |
+LL | trait Foo2<T> where <Self as Foo2<T>>::Baz: Clone {
+ | +++++++++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `<Self as Foo25<T>>::Baz: Clone` is not satisfied
+ --> $DIR/defaults-suitability.rs:74:23
+ |
+LL | type Bar: Clone = Vec<Self::Baz>;
+ | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `<Self as Foo25<T>>::Baz`
+ |
+ = note: required because of the requirements on the impl of `Clone` for `Vec<<Self as Foo25<T>>::Baz>`
+note: required by a bound in `Foo25::Bar`
+ --> $DIR/defaults-suitability.rs:74:15
+ |
+LL | type Bar: Clone = Vec<Self::Baz>;
+ | ^^^^^ required by this bound in `Foo25::Bar`
+help: consider further restricting the associated type
+ |
+LL | trait Foo25<T: Clone> where <Self as Foo25<T>>::Baz: Clone {
+ | ++++++++++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `T: Clone` is not satisfied
+ --> $DIR/defaults-suitability.rs:87:16
+ |
+LL | type Baz = T;
+ | ^ the trait `Clone` is not implemented for `T`
+ |
+note: required by a bound in `Foo3::Baz`
+ --> $DIR/defaults-suitability.rs:84:16
+ |
+LL | Self::Baz: Clone,
+ | ^^^^^ required by this bound in `Foo3::Baz`
+...
+LL | type Baz = T;
+ | --- required by a bound in this
+help: consider further restricting type parameter `T`
+ |
+LL | Self::Baz: Clone, T: std::clone::Clone
+ | ~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.rs b/src/test/ui/associated-types/defaults-unsound-62211-1.rs
new file mode 100644
index 000000000..fa6a208b4
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-unsound-62211-1.rs
@@ -0,0 +1,54 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/62211
+//!
+//! The old implementation of defaults did not check whether the provided
+//! default actually fulfills all bounds on the assoc. type, leading to
+//! unsoundness, demonstrated here as a use-after-free.
+//!
+//! Note that the underlying cause of this is still not yet fixed.
+//! See: https://github.com/rust-lang/rust/issues/33017
+
+#![feature(associated_type_defaults)]
+
+use std::{
+ fmt::Display,
+ ops::{AddAssign, Deref},
+};
+
+trait UncheckedCopy: Sized {
+ // This Output is said to be Copy. Yet we default to Self
+ // and it's accepted, not knowing if Self ineed is Copy
+ type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ //~^ ERROR the trait bound `Self: Copy` is not satisfied
+ //~| ERROR the trait bound `Self: Deref` is not satisfied
+ //~| ERROR cannot add-assign `&'static str` to `Self`
+ //~| ERROR `Self` doesn't implement `std::fmt::Display`
+
+ // We said the Output type was Copy, so we can Copy it freely!
+ fn unchecked_copy(other: &Self::Output) -> Self::Output {
+ (*other)
+ }
+
+ fn make_origin(s: Self) -> Self::Output {
+ s.into()
+ }
+}
+
+impl<T> UncheckedCopy for T {}
+
+fn bug<T: UncheckedCopy>(origin: T) {
+ let origin = T::make_origin(origin);
+ let mut copy = T::unchecked_copy(&origin);
+
+ // assert we indeed have 2 strings pointing to the same buffer.
+ assert_eq!(origin.as_ptr(), copy.as_ptr());
+
+ // Drop the origin. Any use of `copy` is UB.
+ drop(origin);
+
+ copy += "This is invalid!";
+ println!("{}", copy);
+}
+
+fn main() {
+ bug(String::from("hello!"));
+}
diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr
new file mode 100644
index 000000000..5cd1cb4a1
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr
@@ -0,0 +1,68 @@
+error[E0277]: `Self` doesn't implement `std::fmt::Display`
+ --> $DIR/defaults-unsound-62211-1.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ `Self` cannot be formatted with the default formatter
+ |
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-1.rs:20:86
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + std::fmt::Display {
+ | +++++++++++++++++++
+
+error[E0277]: cannot add-assign `&'static str` to `Self`
+ --> $DIR/defaults-unsound-62211-1.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ no implementation for `Self += &'static str`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-1.rs:20:47
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
+ | +++++++++++++++++++++++++
+
+error[E0277]: the trait bound `Self: Deref` is not satisfied
+ --> $DIR/defaults-unsound-62211-1.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ the trait `Deref` is not implemented for `Self`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-1.rs:20:25
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + Deref {
+ | +++++++
+
+error[E0277]: the trait bound `Self: Copy` is not satisfied
+ --> $DIR/defaults-unsound-62211-1.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ the trait `Copy` is not implemented for `Self`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-1.rs:20:18
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + Copy {
+ | ++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.rs b/src/test/ui/associated-types/defaults-unsound-62211-2.rs
new file mode 100644
index 000000000..c13ec776a
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-unsound-62211-2.rs
@@ -0,0 +1,54 @@
+//! Regression test for https://github.com/rust-lang/rust/issues/62211
+//!
+//! The old implementation of defaults did not check whether the provided
+//! default actually fulfills all bounds on the assoc. type, leading to
+//! unsoundness and ICEs, the latter being demonstrated here.
+//!
+//! Note that the underlying cause of this is still not yet fixed.
+//! See: https://github.com/rust-lang/rust/issues/33017
+
+#![feature(associated_type_defaults)]
+
+use std::{
+ fmt::Display,
+ ops::{AddAssign, Deref},
+};
+
+trait UncheckedCopy: Sized {
+ // This Output is said to be Copy. Yet we default to Self
+ // and it's accepted, not knowing if Self ineed is Copy
+ type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ //~^ ERROR the trait bound `Self: Copy` is not satisfied
+ //~| ERROR the trait bound `Self: Deref` is not satisfied
+ //~| ERROR cannot add-assign `&'static str` to `Self`
+ //~| ERROR `Self` doesn't implement `std::fmt::Display`
+
+ // We said the Output type was Copy, so we can Copy it freely!
+ fn unchecked_copy(other: &Self::Output) -> Self::Output {
+ (*other)
+ }
+
+ fn make_origin(s: Self) -> Self::Output {
+ s.into()
+ }
+}
+
+impl<T> UncheckedCopy for T {}
+
+fn bug<T: UncheckedCopy>(origin: T) {
+ let origin = T::make_origin(origin);
+ let mut copy = T::unchecked_copy(&origin);
+
+ // assert we indeed have 2 strings pointing to the same buffer.
+ assert_eq!(origin.as_ptr(), copy.as_ptr());
+
+ // Drop the origin. Any use of `copy` is UB.
+ drop(origin);
+
+ copy += "This is invalid!";
+ println!("{}", copy);
+}
+
+fn main() {
+ bug(());
+}
diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr
new file mode 100644
index 000000000..89319bb75
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr
@@ -0,0 +1,68 @@
+error[E0277]: `Self` doesn't implement `std::fmt::Display`
+ --> $DIR/defaults-unsound-62211-2.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ `Self` cannot be formatted with the default formatter
+ |
+ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-2.rs:20:86
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + std::fmt::Display {
+ | +++++++++++++++++++
+
+error[E0277]: cannot add-assign `&'static str` to `Self`
+ --> $DIR/defaults-unsound-62211-2.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ no implementation for `Self += &'static str`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-2.rs:20:47
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + AddAssign<&'static str> {
+ | +++++++++++++++++++++++++
+
+error[E0277]: the trait bound `Self: Deref` is not satisfied
+ --> $DIR/defaults-unsound-62211-2.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ the trait `Deref` is not implemented for `Self`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-2.rs:20:25
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^^^^^^^^^^^^^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + Deref {
+ | +++++++
+
+error[E0277]: the trait bound `Self: Copy` is not satisfied
+ --> $DIR/defaults-unsound-62211-2.rs:20:96
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ the trait `Copy` is not implemented for `Self`
+ |
+note: required by a bound in `UncheckedCopy::Output`
+ --> $DIR/defaults-unsound-62211-2.rs:20:18
+ |
+LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
+ | ^^^^ required by this bound in `UncheckedCopy::Output`
+help: consider further restricting `Self`
+ |
+LL | trait UncheckedCopy: Sized + Copy {
+ | ++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/defaults-wf.rs b/src/test/ui/associated-types/defaults-wf.rs
new file mode 100644
index 000000000..99b512503
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-wf.rs
@@ -0,0 +1,11 @@
+// Check that associated type defaults are wf checked.
+
+#![feature(associated_type_defaults)]
+
+// Default types must always be wf
+trait Tr3 {
+ type Ty = Vec<[u8]>;
+ //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/defaults-wf.stderr b/src/test/ui/associated-types/defaults-wf.stderr
new file mode 100644
index 000000000..8455f88f1
--- /dev/null
+++ b/src/test/ui/associated-types/defaults-wf.stderr
@@ -0,0 +1,16 @@
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+ --> $DIR/defaults-wf.rs:7:15
+ |
+LL | type Ty = Vec<[u8]>;
+ | ^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[u8]`
+note: required by a bound in `Vec`
+ --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ |
+LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
+ | ^ required by this bound in `Vec`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
new file mode 100644
index 000000000..239f45539
--- /dev/null
+++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+ --> $DIR/higher-ranked-projection.rs:23:5
+ |
+LL | foo(());
+ | ^^^^^^^ one type is more general than the other
+ |
+ = note: expected reference `&'a ()`
+ found reference `&()`
+note: the lifetime requirement is introduced here
+ --> $DIR/higher-ranked-projection.rs:14:33
+ |
+LL | where for<'a> &'a T: Mirror<Image=U>
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr b/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr
new file mode 100644
index 000000000..8b2b87223
--- /dev/null
+++ b/src/test/ui/associated-types/higher-ranked-projection.badbase.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+ --> $DIR/higher-ranked-projection.rs:25:5
+ |
+LL | foo(());
+ | ^^^^^^^ one type is more general than the other
+ |
+ = note: expected reference `&'a ()`
+ found reference `&()`
+note: the lifetime requirement is introduced here
+ --> $DIR/higher-ranked-projection.rs:16:33
+ |
+LL | where for<'a> &'a T: Mirror<Image=U>
+ | ^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr b/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr
new file mode 100644
index 000000000..217392aa3
--- /dev/null
+++ b/src/test/ui/associated-types/higher-ranked-projection.badnll.stderr
@@ -0,0 +1,2 @@
+error: unknown debugging option: `borrowck`
+
diff --git a/src/test/ui/associated-types/higher-ranked-projection.rs b/src/test/ui/associated-types/higher-ranked-projection.rs
new file mode 100644
index 000000000..7e6c509a2
--- /dev/null
+++ b/src/test/ui/associated-types/higher-ranked-projection.rs
@@ -0,0 +1,25 @@
+// revisions: good bad
+//[good] check-pass
+
+trait Mirror {
+ type Image;
+}
+
+impl<T> Mirror for T {
+ type Image = T;
+}
+
+#[cfg(bad)]
+fn foo<U, T>(_t: T)
+ where for<'a> &'a T: Mirror<Image=U>
+{}
+
+#[cfg(good)]
+fn foo<U, T>(_t: T)
+ where for<'a> &'a T: Mirror<Image=&'a U>
+{}
+
+fn main() {
+ foo(());
+ //[bad]~^ ERROR mismatched types
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-1.rs b/src/test/ui/associated-types/hr-associated-type-bound-1.rs
new file mode 100644
index 000000000..db414164e
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-1.rs
@@ -0,0 +1,18 @@
+trait X<'a>
+where
+ for<'b> <Self as X<'b>>::U: Clone,
+{
+ type U: ?Sized;
+ fn f(&self, x: &Self::U) {
+ <Self::U>::clone(x);
+ }
+}
+
+impl X<'_> for i32 {
+ type U = str;
+ //~^ ERROR the trait bound `str: Clone`
+}
+
+fn main() {
+ 1i32.f("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-1.stderr b/src/test/ui/associated-types/hr-associated-type-bound-1.stderr
new file mode 100644
index 000000000..73b5e1053
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-1.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-1.rs:12:14
+ |
+LL | type U = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X`
+ --> $DIR/hr-associated-type-bound-1.rs:3:33
+ |
+LL | trait X<'a>
+ | - required by a bound in this
+LL | where
+LL | for<'b> <Self as X<'b>>::U: Clone,
+ | ^^^^^ required by this bound in `X`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-2.rs b/src/test/ui/associated-types/hr-associated-type-bound-2.rs
new file mode 100644
index 000000000..a89f61a81
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-2.rs
@@ -0,0 +1,20 @@
+trait X<'a>
+where
+ for<'b> <Self as X<'b>>::U: Clone,
+{
+ type U: ?Sized;
+ fn f(&self, x: &Self::U) {
+ <Self::U>::clone(x);
+ }
+}
+
+impl X<'_> for u32 //~ overflow evaluating the requirement `for<'b> u32: X<'b>`
+where
+ for<'b> <Self as X<'b>>::U: Clone,
+{
+ type U = str;
+}
+
+fn main() {
+ 1u32.f("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
new file mode 100644
index 000000000..e007f5a16
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-2.stderr
@@ -0,0 +1,18 @@
+error[E0275]: overflow evaluating the requirement `for<'b> u32: X<'b>`
+ --> $DIR/hr-associated-type-bound-2.rs:11:1
+ |
+LL | impl X<'_> for u32
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`hr_associated_type_bound_2`)
+note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
+ --> $DIR/hr-associated-type-bound-2.rs:11:6
+ |
+LL | impl X<'_> for u32
+ | ^^^^^ ^^^
+ = note: 128 redundant requirements hidden
+ = note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-object.rs b/src/test/ui/associated-types/hr-associated-type-bound-object.rs
new file mode 100644
index 000000000..e19c918c3
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-object.rs
@@ -0,0 +1,14 @@
+trait X<'a>
+where
+ for<'b> <Self as X<'b>>::U: Clone,
+{
+ type U: ?Sized;
+}
+fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) {
+ //~^ ERROR the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
+ <<T as X<'_>>::U>::clone(x);
+}
+
+pub fn main() {
+ f::<dyn X<'_, U = str>>("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-object.stderr b/src/test/ui/associated-types/hr-associated-type-bound-object.stderr
new file mode 100644
index 000000000..6d19186bd
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-object.stderr
@@ -0,0 +1,18 @@
+error[E0277]: the trait bound `for<'b> <T as X<'b>>::U: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-object.rs:7:13
+ |
+LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) {
+ | ^^^^^ the trait `for<'b> Clone` is not implemented for `<T as X<'b>>::U`
+ |
+note: required by a bound in `X`
+ --> $DIR/hr-associated-type-bound-object.rs:3:33
+ |
+LL | trait X<'a>
+ | - required by a bound in this
+LL | where
+LL | for<'b> <Self as X<'b>>::U: Clone,
+ | ^^^^^ required by this bound in `X`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-1.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-1.rs
new file mode 100644
index 000000000..bbeeb145d
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-1.rs
@@ -0,0 +1,20 @@
+trait Y<'a, T: ?Sized>
+where
+ T: Y<'a, Self>,
+ for<'b> <Self as Y<'b, T>>::V: Clone,
+ for<'b> <T as Y<'b, Self>>::V: Clone,
+{
+ type V: ?Sized;
+ fn g(&self, x: &Self::V) {
+ <Self::V>::clone(x);
+ }
+}
+
+impl<'a> Y<'a, u8> for u8 {
+ type V = str;
+ //~^ ERROR the trait bound `str: Clone` is not satisfied
+}
+
+fn main() {
+ 1u8.g("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-1.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-1.stderr
new file mode 100644
index 000000000..af2e61689
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-1.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-1.rs:14:14
+ |
+LL | type V = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Y`
+ --> $DIR/hr-associated-type-bound-param-1.rs:4:36
+ |
+LL | trait Y<'a, T: ?Sized>
+ | - required by a bound in this
+...
+LL | for<'b> <Self as Y<'b, T>>::V: Clone,
+ | ^^^^^ required by this bound in `Y`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs
new file mode 100644
index 000000000..f74c5a859
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-2.rs
@@ -0,0 +1,21 @@
+trait Z<'a, T: ?Sized>
+where
+ T: Z<'a, u16>,
+ //~^ the trait bound `str: Clone` is not satisfied
+ //~| the trait bound `str: Clone` is not satisfied
+ for<'b> <T as Z<'b, u16>>::W: Clone,
+{
+ type W: ?Sized;
+ fn h(&self, x: &T::W) {
+ <T::W>::clone(x);
+ }
+}
+
+impl<'a> Z<'a, u16> for u16 {
+ type W = str;
+ //~^ ERROR the trait bound `str: Clone
+}
+
+fn main() {
+ 1u16.h("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr
new file mode 100644
index 000000000..52294f8c9
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr
@@ -0,0 +1,51 @@
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-2.rs:3:8
+ |
+LL | T: Z<'a, u16>,
+ | ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Z`
+ --> $DIR/hr-associated-type-bound-param-2.rs:6:35
+ |
+LL | trait Z<'a, T: ?Sized>
+ | - required by a bound in this
+...
+LL | for<'b> <T as Z<'b, u16>>::W: Clone,
+ | ^^^^^ required by this bound in `Z`
+
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-2.rs:15:14
+ |
+LL | type W = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Z`
+ --> $DIR/hr-associated-type-bound-param-2.rs:6:35
+ |
+LL | trait Z<'a, T: ?Sized>
+ | - required by a bound in this
+...
+LL | for<'b> <T as Z<'b, u16>>::W: Clone,
+ | ^^^^^ required by this bound in `Z`
+
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-2.rs:3:8
+ |
+LL | T: Z<'a, u16>,
+ | ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `Z`
+ --> $DIR/hr-associated-type-bound-param-2.rs:6:35
+ |
+LL | trait Z<'a, T: ?Sized>
+ | - required by a bound in this
+...
+LL | for<'b> <T as Z<'b, u16>>::W: Clone,
+ | ^^^^^ required by this bound in `Z`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-3.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-3.rs
new file mode 100644
index 000000000..fda7d8111
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-3.rs
@@ -0,0 +1,19 @@
+trait X<'a, T>
+where
+ for<'b> T: X<'b, T>,
+ for<'b> <T as X<'b, T>>::U: Clone,
+{
+ type U: ?Sized;
+ fn f(x: &<T as X<'_, T>>::U) {
+ <<T as X<'_, T>>::U>::clone(x);
+ }
+}
+
+impl<S, T> X<'_, (T,)> for (S,) {
+ type U = str;
+ //~^ ERROR the trait bound `str: Clone` is not satisfied
+}
+
+pub fn main() {
+ <(i32,) as X<(i32,)>>::f("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-3.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-3.stderr
new file mode 100644
index 000000000..84d5e0494
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-3.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-3.rs:13:14
+ |
+LL | type U = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X`
+ --> $DIR/hr-associated-type-bound-param-3.rs:4:33
+ |
+LL | trait X<'a, T>
+ | - required by a bound in this
+...
+LL | for<'b> <T as X<'b, T>>::U: Clone,
+ | ^^^^^ required by this bound in `X`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-4.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-4.rs
new file mode 100644
index 000000000..20c8157ed
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-4.rs
@@ -0,0 +1,19 @@
+trait X<'a, T>
+where
+ for<'b> (T,): X<'b, T>,
+ for<'b> <(T,) as X<'b, T>>::U: Clone,
+{
+ type U: ?Sized;
+ fn f(x: &<(T,) as X<'_, T>>::U) {
+ <<(T,) as X<'_, T>>::U>::clone(x);
+ }
+}
+
+impl<S, T> X<'_, T> for (S,) {
+ type U = str;
+ //~^ ERROR the trait bound `str: Clone` is not satisfied
+}
+
+pub fn main() {
+ <(i32,) as X<i32>>::f("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-4.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-4.stderr
new file mode 100644
index 000000000..ee1d5d324
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-4.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-4.rs:13:14
+ |
+LL | type U = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X`
+ --> $DIR/hr-associated-type-bound-param-4.rs:4:36
+ |
+LL | trait X<'a, T>
+ | - required by a bound in this
+...
+LL | for<'b> <(T,) as X<'b, T>>::U: Clone,
+ | ^^^^^ required by this bound in `X`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs
new file mode 100644
index 000000000..d7f3151a5
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-5.rs
@@ -0,0 +1,37 @@
+trait Cycle: Sized {
+ type Next: Cycle<Next = Self>;
+}
+
+impl<T> Cycle for Box<T> {
+ type Next = Vec<T>;
+}
+
+impl<T> Cycle for Vec<T> {
+ type Next = Box<T>;
+}
+
+trait X<'a, T: Cycle + for<'b> X<'b, T>>
+where
+ for<'b> <T as X<'b, T>>::U: Clone,
+ for<'b> T::Next: X<'b, T::Next>,
+ for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
+{
+ type U: ?Sized;
+ fn f(x: &<T as X<'_, T>>::U) {
+ <<T as X<'_, T>>::U>::clone(x);
+ }
+}
+
+impl<S, T> X<'_, Vec<T>> for S {
+ type U = str;
+ //~^ ERROR the trait bound `str: Clone` is not satisfied
+}
+
+impl<S, T> X<'_, Box<T>> for S {
+ type U = str;
+ //~^ ERROR the trait bound `str: Clone` is not satisfied
+}
+
+pub fn main() {
+ <i32 as X<Box<i32>>>::f("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr
new file mode 100644
index 000000000..ece3151ba
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr
@@ -0,0 +1,35 @@
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-5.rs:26:14
+ |
+LL | type U = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X`
+ --> $DIR/hr-associated-type-bound-param-5.rs:17:45
+ |
+LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
+ | - required by a bound in this
+...
+LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
+ | ^^^^^ required by this bound in `X`
+
+error[E0277]: the trait bound `str: Clone` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-5.rs:31:14
+ |
+LL | type U = str;
+ | ^^^ the trait `Clone` is not implemented for `str`
+ |
+ = help: the trait `Clone` is implemented for `String`
+note: required by a bound in `X`
+ --> $DIR/hr-associated-type-bound-param-5.rs:17:45
+ |
+LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
+ | - required by a bound in this
+...
+LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
+ | ^^^^^ required by this bound in `X`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-6.rs b/src/test/ui/associated-types/hr-associated-type-bound-param-6.rs
new file mode 100644
index 000000000..482047b09
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-6.rs
@@ -0,0 +1,19 @@
+trait X<'a, T>
+where
+ for<'b> T: X<'b, T>,
+ for<'b> <T as X<'b, T>>::U: Clone,
+{
+ type U: ?Sized;
+ fn f(x: &<T as X<'_, T>>::U) {
+ <<T as X<'_, T>>::U>::clone(x);
+ }
+}
+
+impl<S, T> X<'_, T> for (S,) {
+ //~^ ERROR the trait bound `for<'b> T: X<'b, T>` is not satisfied
+ type U = str;
+}
+
+pub fn main() {
+ <(i32,) as X<i32>>::f("abc");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-bound-param-6.stderr b/src/test/ui/associated-types/hr-associated-type-bound-param-6.stderr
new file mode 100644
index 000000000..bd6e627a3
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-bound-param-6.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `for<'b> T: X<'b, T>` is not satisfied
+ --> $DIR/hr-associated-type-bound-param-6.rs:12:12
+ |
+LL | impl<S, T> X<'_, T> for (S,) {
+ | ^^^^^^^^ the trait `for<'b> X<'b, T>` is not implemented for `T`
+ |
+help: consider restricting type parameter `T`
+ |
+LL | impl<S, T: for<'b> X<'b, T>> X<'_, T> for (S,) {
+ | ++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/hr-associated-type-projection-1.rs b/src/test/ui/associated-types/hr-associated-type-projection-1.rs
new file mode 100644
index 000000000..951dd9e97
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-projection-1.rs
@@ -0,0 +1,20 @@
+trait UnsafeCopy<'a, T: Copy>
+where
+ for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
+{
+ type Item;
+
+ fn bug(item: &Self::Item) -> () {
+ let x: T = **item;
+ &x as *const _;
+ }
+}
+
+impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
+ //~^ type mismatch resolving `<T as Deref>::Target == T`
+ type Item = T;
+}
+
+pub fn main() {
+ <&'static str>::bug(&"");
+}
diff --git a/src/test/ui/associated-types/hr-associated-type-projection-1.stderr b/src/test/ui/associated-types/hr-associated-type-projection-1.stderr
new file mode 100644
index 000000000..a65f84ae5
--- /dev/null
+++ b/src/test/ui/associated-types/hr-associated-type-projection-1.stderr
@@ -0,0 +1,24 @@
+error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
+ --> $DIR/hr-associated-type-projection-1.rs:13:33
+ |
+LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
+ | - this type parameter ^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
+ |
+ = note: expected type parameter `T`
+ found associated type `<T as Deref>::Target`
+note: required by a bound in `UnsafeCopy`
+ --> $DIR/hr-associated-type-projection-1.rs:3:64
+ |
+LL | trait UnsafeCopy<'a, T: Copy>
+ | ---------- required by a bound in this
+LL | where
+LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
+ | ^^^^^^^^^^ required by this bound in `UnsafeCopy`
+help: consider further restricting this bound
+ |
+LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<'_, T> for T {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs
new file mode 100644
index 000000000..1de1ddbe3
--- /dev/null
+++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs
@@ -0,0 +1,32 @@
+trait Foo {
+ type Item;
+}
+
+trait Bar: Foo {}
+
+struct S;
+
+impl Foo for S {
+ type Item = i32;
+}
+impl Bar for S {}
+
+struct T;
+
+impl Foo for T {
+ type Item = u32;
+}
+impl Bar for T {}
+
+fn bar() -> impl Bar {
+ T
+}
+
+fn baz() -> impl Bar<Item = i32> {
+ //~^ ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32`
+ bar()
+}
+
+fn main() {
+ let _ = baz();
+}
diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
new file mode 100644
index 000000000..fbd76a64c
--- /dev/null
+++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
@@ -0,0 +1,24 @@
+error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32`
+ --> $DIR/impl-trait-return-missing-constraint.rs:25:13
+ |
+LL | fn bar() -> impl Bar {
+ | -------- the expected opaque type
+...
+LL | fn baz() -> impl Bar<Item = i32> {
+ | ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
+LL |
+LL | bar()
+ | ----- return type was inferred to be `impl Bar` here
+ |
+ = note: expected associated type `<impl Bar as Foo>::Item`
+ found type `i32`
+ = help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` or calling a method that returns `<impl Bar as Foo>::Item`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
+ |
+LL | fn bar() -> impl Bar<Item = i32> {
+ | ++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.rs b/src/test/ui/associated-types/impl-wf-cycle-1.rs
new file mode 100644
index 000000000..365eddaed
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.rs
@@ -0,0 +1,27 @@
+// Regression test for #79714
+
+trait Baz {}
+impl Baz for () {}
+impl<T> Baz for (T,) {}
+
+trait Fiz {}
+impl Fiz for bool {}
+
+trait Grault {
+ type A;
+ type B;
+}
+
+impl<T: Grault> Grault for (T,)
+//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+where
+ Self::A: Baz,
+ Self::B: Fiz,
+{
+ type A = ();
+ type B = bool;
+}
+
+fn main() {
+ let x: <(_,) as Grault>::A = ();
+}
diff --git a/src/test/ui/associated-types/impl-wf-cycle-1.stderr b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
new file mode 100644
index 000000000..939c9bbdb
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-1.stderr
@@ -0,0 +1,17 @@
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+ --> $DIR/impl-wf-cycle-1.rs:15:1
+ |
+LL | impl<T: Grault> Grault for (T,)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: required because of the requirements on the impl of `Grault` for `(T,)`
+ --> $DIR/impl-wf-cycle-1.rs:15:17
+ |
+LL | impl<T: Grault> Grault for (T,)
+ | ^^^^^^ ^^^^
+ = note: 1 redundant requirement hidden
+ = note: required because of the requirements on the impl of `Grault` for `(T,)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.rs b/src/test/ui/associated-types/impl-wf-cycle-2.rs
new file mode 100644
index 000000000..f2f3072e3
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.rs
@@ -0,0 +1,15 @@
+// Regression test for #79714
+
+trait Grault {
+ type A;
+}
+
+impl<T: Grault> Grault for (T,)
+//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
+where
+ Self::A: Copy,
+{
+ type A = ();
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/impl-wf-cycle-2.stderr b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
new file mode 100644
index 000000000..d02ed2cac
--- /dev/null
+++ b/src/test/ui/associated-types/impl-wf-cycle-2.stderr
@@ -0,0 +1,15 @@
+error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
+ --> $DIR/impl-wf-cycle-2.rs:7:1
+ |
+LL | impl<T: Grault> Grault for (T,)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: required because of the requirements on the impl of `Grault` for `(T,)`
+ --> $DIR/impl-wf-cycle-2.rs:7:17
+ |
+LL | impl<T: Grault> Grault for (T,)
+ | ^^^^^^ ^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/associated-types/issue-18655.rs b/src/test/ui/associated-types/issue-18655.rs
new file mode 100644
index 000000000..3d18542ac
--- /dev/null
+++ b/src/test/ui/associated-types/issue-18655.rs
@@ -0,0 +1,22 @@
+// run-pass
+trait Factory {
+ type Product;
+ fn create(&self) -> <Self as Factory>::Product;
+}
+
+impl Factory for f64 {
+ type Product = f64;
+ fn create(&self) -> f64 { *self * *self }
+}
+
+impl<A: Factory, B: Factory> Factory for (A, B) {
+ type Product = (<A as Factory>::Product, <B as Factory>::Product);
+ fn create(&self) -> (<A as Factory>::Product, <B as Factory>::Product) {
+ let (ref a, ref b) = *self;
+ (a.create(), b.create())
+ }
+}
+
+fn main() {
+ assert_eq!((16., 25.), (4., 5.).create());
+}
diff --git a/src/test/ui/associated-types/issue-19081.rs b/src/test/ui/associated-types/issue-19081.rs
new file mode 100644
index 000000000..fbfe4c6f8
--- /dev/null
+++ b/src/test/ui/associated-types/issue-19081.rs
@@ -0,0 +1,14 @@
+// check-pass
+pub trait Hasher {
+ type State;
+
+ fn hash<T: Hash<
+ <Self as Hasher>::State
+ >>(&self, value: &T) -> u64;
+}
+
+pub trait Hash<S> {
+ fn hash(&self, state: &mut S);
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-19883.rs b/src/test/ui/associated-types/issue-19883.rs
new file mode 100644
index 000000000..5cf422043
--- /dev/null
+++ b/src/test/ui/associated-types/issue-19883.rs
@@ -0,0 +1,16 @@
+trait From<Src> {
+ type Output;
+
+ fn from(src: Src) -> <Self as From<Src>>::Output;
+}
+
+trait To: Sized {
+ fn to<Dst: From<Self>>(self) ->
+ <Dst as From<Self>>::Dst
+ //~^ ERROR cannot find associated type `Dst` in trait `From`
+ {
+ From::from(self)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-19883.stderr b/src/test/ui/associated-types/issue-19883.stderr
new file mode 100644
index 000000000..bd6a86b74
--- /dev/null
+++ b/src/test/ui/associated-types/issue-19883.stderr
@@ -0,0 +1,15 @@
+error[E0576]: cannot find associated type `Dst` in trait `From`
+ --> $DIR/issue-19883.rs:9:30
+ |
+LL | type Output;
+ | ------------ associated type `Output` defined here
+...
+LL | <Dst as From<Self>>::Dst
+ | ^^^
+ | |
+ | not found in `From`
+ | help: maybe you meant this associated type: `Output`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0576`.
diff --git a/src/test/ui/associated-types/issue-20005.rs b/src/test/ui/associated-types/issue-20005.rs
new file mode 100644
index 000000000..36350bff1
--- /dev/null
+++ b/src/test/ui/associated-types/issue-20005.rs
@@ -0,0 +1,15 @@
+trait From<Src> {
+ type Result;
+
+ fn from(src: Src) -> Self::Result;
+}
+
+trait To {
+ fn to<Dst>(
+ self
+ ) -> <Dst as From<Self>>::Result where Dst: From<Self> { //~ ERROR the size for values of type
+ From::from(self)
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-20005.stderr b/src/test/ui/associated-types/issue-20005.stderr
new file mode 100644
index 000000000..c8e57df0d
--- /dev/null
+++ b/src/test/ui/associated-types/issue-20005.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+ --> $DIR/issue-20005.rs:10:49
+ |
+LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
+ | ^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+note: required by a bound in `From`
+ --> $DIR/issue-20005.rs:1:12
+ |
+LL | trait From<Src> {
+ | ^^^ required by this bound in `From`
+help: consider further restricting `Self`
+ |
+LL | ) -> <Dst as From<Self>>::Result where Dst: From<Self>, Self: Sized {
+ | +++++++++++++
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | trait From<Src: ?Sized> {
+ | ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-20825-2.rs b/src/test/ui/associated-types/issue-20825-2.rs
new file mode 100644
index 000000000..b79a29730
--- /dev/null
+++ b/src/test/ui/associated-types/issue-20825-2.rs
@@ -0,0 +1,10 @@
+// check-pass
+pub trait Subscriber {
+ type Input;
+}
+
+pub trait Processor: Subscriber<Input = <Self as Processor>::Input> {
+ type Input;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-20825.rs b/src/test/ui/associated-types/issue-20825.rs
new file mode 100644
index 000000000..516c304d8
--- /dev/null
+++ b/src/test/ui/associated-types/issue-20825.rs
@@ -0,0 +1,10 @@
+pub trait Subscriber {
+ type Input;
+}
+
+pub trait Processor: Subscriber<Input = Self::Input> {
+ //~^ ERROR cycle detected
+ type Input;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-20825.stderr b/src/test/ui/associated-types/issue-20825.stderr
new file mode 100644
index 000000000..be2bbd448
--- /dev/null
+++ b/src/test/ui/associated-types/issue-20825.stderr
@@ -0,0 +1,16 @@
+error[E0391]: cycle detected when computing the super traits of `Processor` with associated type name `Input`
+ --> $DIR/issue-20825.rs:5:1
+ |
+LL | pub trait Processor: Subscriber<Input = Self::Input> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: ...which immediately requires computing the super traits of `Processor` with associated type name `Input` again
+note: cycle used when computing the super traits of `Processor`
+ --> $DIR/issue-20825.rs:5:1
+ |
+LL | pub trait Processor: Subscriber<Input = Self::Input> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/associated-types/issue-21363.rs b/src/test/ui/associated-types/issue-21363.rs
new file mode 100644
index 000000000..acc28cb43
--- /dev/null
+++ b/src/test/ui/associated-types/issue-21363.rs
@@ -0,0 +1,15 @@
+// check-pass
+// pretty-expanded FIXME #23616
+
+#![no_implicit_prelude]
+
+trait Iterator {
+ type Item;
+ fn dummy(&self) { }
+}
+
+impl<'a, T> Iterator for &'a mut (dyn Iterator<Item=T> + 'a) {
+ type Item = T;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-21726.rs b/src/test/ui/associated-types/issue-21726.rs
new file mode 100644
index 000000000..b98cf2166
--- /dev/null
+++ b/src/test/ui/associated-types/issue-21726.rs
@@ -0,0 +1,38 @@
+// check-pass
+#![allow(dead_code)]
+// Regression test for #21726: an issue arose around the rules for
+// subtyping of projection types that resulted in an unconstrained
+// region, yielding region inference failures.
+
+// pretty-expanded FIXME #23616
+
+fn main() { }
+
+fn foo<'a>(s: &'a str) {
+ let b: B<()> = B::new(s, ());
+ b.get_short();
+}
+
+trait IntoRef<'a> {
+ type T: Clone;
+ fn into_ref(self, _: &'a str) -> Self::T;
+}
+
+impl<'a> IntoRef<'a> for () {
+ type T = &'a str;
+ fn into_ref(self, s: &'a str) -> &'a str {
+ s
+ }
+}
+
+struct B<'a, P: IntoRef<'a>>(P::T);
+
+impl<'a, P: IntoRef<'a>> B<'a, P> {
+ fn new(s: &'a str, i: P) -> B<'a, P> {
+ B(i.into_ref(s))
+ }
+
+ fn get_short(&self) -> P::T {
+ self.0.clone()
+ }
+}
diff --git a/src/test/ui/associated-types/issue-22037.rs b/src/test/ui/associated-types/issue-22037.rs
new file mode 100644
index 000000000..b9eb41b6e
--- /dev/null
+++ b/src/test/ui/associated-types/issue-22037.rs
@@ -0,0 +1,17 @@
+trait A {
+ type Output;
+ fn a(&self) -> <Self as A>::X;
+ //~^ ERROR cannot find associated type `X` in trait `A`
+}
+
+impl A for u32 {
+ type Output = u32;
+ fn a(&self) -> u32 {
+ 0
+ }
+}
+
+fn main() {
+ let a: u32 = 0;
+ let b: u32 = a.a();
+}
diff --git a/src/test/ui/associated-types/issue-22037.stderr b/src/test/ui/associated-types/issue-22037.stderr
new file mode 100644
index 000000000..0e019f10f
--- /dev/null
+++ b/src/test/ui/associated-types/issue-22037.stderr
@@ -0,0 +1,14 @@
+error[E0576]: cannot find associated type `X` in trait `A`
+ --> $DIR/issue-22037.rs:3:33
+ |
+LL | type Output;
+ | ------------ associated type `Output` defined here
+LL | fn a(&self) -> <Self as A>::X;
+ | ^
+ | |
+ | not found in `A`
+ | help: maybe you meant this associated type: `Output`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0576`.
diff --git a/src/test/ui/associated-types/issue-22066.rs b/src/test/ui/associated-types/issue-22066.rs
new file mode 100644
index 000000000..8e8ba5dc4
--- /dev/null
+++ b/src/test/ui/associated-types/issue-22066.rs
@@ -0,0 +1,12 @@
+// check-pass
+pub trait LineFormatter<'a> {
+ type Iter: Iterator<Item=&'a str> + 'a;
+ fn iter(&'a self, line: &'a str) -> Self::Iter;
+
+ fn dimensions(&'a self, line: &'a str) {
+ let iter: Self::Iter = self.iter(line);
+ <_ as IntoIterator>::into_iter(iter);
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-22560.rs b/src/test/ui/associated-types/issue-22560.rs
new file mode 100644
index 000000000..44be8817b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-22560.rs
@@ -0,0 +1,15 @@
+trait Add<Rhs=Self> {
+ type Output;
+}
+
+trait Sub<Rhs=Self> {
+ type Output;
+}
+
+type Test = dyn Add + Sub;
+//~^ ERROR E0393
+//~| ERROR E0191
+//~| ERROR E0393
+//~| ERROR E0225
+
+fn main() { }
diff --git a/src/test/ui/associated-types/issue-22560.stderr b/src/test/ui/associated-types/issue-22560.stderr
new file mode 100644
index 000000000..700923c1b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-22560.stderr
@@ -0,0 +1,56 @@
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/issue-22560.rs:9:23
+ |
+LL | trait Sub<Rhs=Self> {
+ | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ help: set the type parameter to the desired type: `Sub<Rhs>`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0393]: the type parameter `Rhs` must be explicitly specified
+ --> $DIR/issue-22560.rs:9:17
+ |
+LL | trait Add<Rhs=Self> {
+ | ------------------- type parameter `Rhs` must be specified for this
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ help: set the type parameter to the desired type: `Add<Rhs>`
+ |
+ = note: because of the default `Self` reference, type parameters must be specified on object types
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/issue-22560.rs:9:23
+ |
+LL | type Test = dyn Add + Sub;
+ | --- ^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
+ --> $DIR/issue-22560.rs:9:17
+ |
+LL | type Output;
+ | ----------- `Output` defined here
+...
+LL | type Output;
+ | ----------- `Output` defined here
+...
+LL | type Test = dyn Add + Sub;
+ | ^^^ ^^^ associated type `Output` must be specified
+ | |
+ | associated type `Output` must be specified
+ |
+help: specify the associated types
+ |
+LL | type Test = dyn Add<Output = Type> + Sub<Output = Type>;
+ | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0191, E0225, E0393.
+For more information about an error, try `rustc --explain E0191`.
diff --git a/src/test/ui/associated-types/issue-22828.rs b/src/test/ui/associated-types/issue-22828.rs
new file mode 100644
index 000000000..adf4dd6ce
--- /dev/null
+++ b/src/test/ui/associated-types/issue-22828.rs
@@ -0,0 +1,23 @@
+// run-pass
+#![allow(dead_code)]
+// Test transitive analysis for associated types. Collected types
+// should be normalized and new obligations generated.
+
+// pretty-expanded FIXME #23616
+
+trait Foo {
+ type A;
+ fn foo(&self) {}
+}
+
+impl Foo for usize {
+ type A = usize;
+}
+
+struct Bar<T: Foo> { inner: T::A }
+
+fn is_send<T: Send>() {}
+
+fn main() {
+ is_send::<Bar<usize>>();
+}
diff --git a/src/test/ui/associated-types/issue-23208.rs b/src/test/ui/associated-types/issue-23208.rs
new file mode 100644
index 000000000..fd4ffe5d6
--- /dev/null
+++ b/src/test/ui/associated-types/issue-23208.rs
@@ -0,0 +1,26 @@
+// run-pass
+trait TheTrait : TheSuperTrait<<Self as TheTrait>::Item> {
+ type Item;
+}
+
+trait TheSuperTrait<T> {
+ fn get(&self) -> T;
+}
+
+impl TheTrait for i32 {
+ type Item = u32;
+}
+
+impl TheSuperTrait<u32> for i32 {
+ fn get(&self) -> u32 {
+ *self as u32
+ }
+}
+
+fn foo<T:TheTrait<Item=u32>>(t: &T) -> u32 {
+ t.get()
+}
+
+fn main() {
+ foo::<i32>(&22);
+}
diff --git a/src/test/ui/associated-types/issue-23595-1.rs b/src/test/ui/associated-types/issue-23595-1.rs
new file mode 100644
index 000000000..483c205f4
--- /dev/null
+++ b/src/test/ui/associated-types/issue-23595-1.rs
@@ -0,0 +1,14 @@
+#![feature(associated_type_defaults)]
+
+use std::ops::Index;
+
+trait Hierarchy {
+ type Value;
+ type ChildKey;
+ type Children = dyn Index<Self::ChildKey, Output=dyn Hierarchy>;
+ //~^ ERROR: the value of the associated types
+
+ fn data(&self) -> Option<(Self::Value, Self::Children)>;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-23595-1.stderr b/src/test/ui/associated-types/issue-23595-1.stderr
new file mode 100644
index 000000000..4307477a5
--- /dev/null
+++ b/src/test/ui/associated-types/issue-23595-1.stderr
@@ -0,0 +1,13 @@
+error[E0191]: the value of the associated types `ChildKey` (from trait `Hierarchy`), `Children` (from trait `Hierarchy`), `Value` (from trait `Hierarchy`) must be specified
+ --> $DIR/issue-23595-1.rs:8:58
+ |
+LL | type Value;
+ | ---------- `Value` defined here
+LL | type ChildKey;
+ | ------------- `ChildKey` defined here
+LL | type Children = dyn Index<Self::ChildKey, Output=dyn Hierarchy>;
+ | ------------- `Children` defined here ^^^^^^^^^ help: specify the associated types: `Hierarchy<Value = Type, ChildKey = Type, Children = Type>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0191`.
diff --git a/src/test/ui/associated-types/issue-23595-2.rs b/src/test/ui/associated-types/issue-23595-2.rs
new file mode 100644
index 000000000..2bfee7a35
--- /dev/null
+++ b/src/test/ui/associated-types/issue-23595-2.rs
@@ -0,0 +1,10 @@
+#![feature(associated_type_defaults)]
+
+pub struct C<AType: A> {a:AType}
+
+pub trait A {
+ type B = C<Self::anything_here_kills_it>;
+ //~^ ERROR: associated type `anything_here_kills_it` not found for `Self`
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-23595-2.stderr b/src/test/ui/associated-types/issue-23595-2.stderr
new file mode 100644
index 000000000..dded673f6
--- /dev/null
+++ b/src/test/ui/associated-types/issue-23595-2.stderr
@@ -0,0 +1,9 @@
+error[E0220]: associated type `anything_here_kills_it` not found for `Self`
+ --> $DIR/issue-23595-2.rs:6:22
+ |
+LL | type B = C<Self::anything_here_kills_it>;
+ | ^^^^^^^^^^^^^^^^^^^^^^ associated type `anything_here_kills_it` not found
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/associated-types/issue-24159.rs b/src/test/ui/associated-types/issue-24159.rs
new file mode 100644
index 000000000..49753e7bf
--- /dev/null
+++ b/src/test/ui/associated-types/issue-24159.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+#![allow(unused)]
+
+trait Bar<T> {
+ fn dummy(&self);
+}
+
+trait Foo {
+ type A;
+ type B: Bar<Self::A>;
+
+ fn get_b(&self) -> &Self::B;
+}
+
+fn test_bar<A, B: Bar<A>>(_: &B) {}
+
+fn test<A, F: Foo<A = A>>(f: &F) {
+ test_bar(f.get_b());
+}
+
+trait Bar1<T> {}
+trait Caz1 {
+ type A;
+ type B: Bar1<Self::A>;
+}
+
+fn test1<T, U>() where T: Caz1, U: Caz1<A = T::A> {}
+
+trait Bar2<T> {}
+trait Caz2 {
+ type A;
+ type B: Bar2<Self::A>;
+}
+fn test2<T: Caz2<A = ()>>() {}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-24204.rs b/src/test/ui/associated-types/issue-24204.rs
new file mode 100644
index 000000000..5a7b34595
--- /dev/null
+++ b/src/test/ui/associated-types/issue-24204.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+#![allow(dead_code)]
+
+trait MultiDispatch<T> {
+ type O;
+}
+
+trait Trait: Sized {
+ type A: MultiDispatch<Self::B, O = Self>;
+ type B;
+
+ fn new<U>(u: U) -> <Self::A as MultiDispatch<U>>::O
+ where
+ Self::A: MultiDispatch<U>;
+}
+
+fn test<T: Trait<B = i32>>(b: i32) -> T
+where
+ T::A: MultiDispatch<i32>,
+{
+ T::new(b)
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-24338.rs b/src/test/ui/associated-types/issue-24338.rs
new file mode 100644
index 000000000..3a2c790f8
--- /dev/null
+++ b/src/test/ui/associated-types/issue-24338.rs
@@ -0,0 +1,21 @@
+//
+// check-pass
+
+trait DictLike<'a> {
+ type ItemsIterator: Iterator<Item=u8>;
+ fn get(c: Self::ItemsIterator) {
+ c.into_iter();
+ }
+}
+
+trait DictLike2<'a> {
+ type ItemsIterator: Iterator<Item=u8>;
+
+ fn items(&self) -> Self::ItemsIterator;
+
+ fn get(&self) {
+ for _ in self.items() {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-25339.rs b/src/test/ui/associated-types/issue-25339.rs
new file mode 100644
index 000000000..6f8ec7009
--- /dev/null
+++ b/src/test/ui/associated-types/issue-25339.rs
@@ -0,0 +1,31 @@
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![feature(associated_type_defaults)]
+
+use std::marker::PhantomData;
+
+pub trait Routing<I> {
+ type Output;
+ fn resolve(&self, input: I);
+}
+
+pub trait ToRouting {
+ type Input;
+ type Routing : ?Sized = dyn Routing<Self::Input, Output=()>;
+ fn to_routing(self) -> Self::Routing;
+}
+
+pub struct Mount<I, R: Routing<I>> {
+ action: R,
+ _marker: PhantomData<I>
+}
+
+impl<I, R: Routing<I>> Mount<I, R> {
+ pub fn create<T: ToRouting<Routing=R>>(mount: &str, input: T) {
+ input.to_routing();
+ }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/issue-26681.rs b/src/test/ui/associated-types/issue-26681.rs
new file mode 100644
index 000000000..a0a8c86d9
--- /dev/null
+++ b/src/test/ui/associated-types/issue-26681.rs
@@ -0,0 +1,20 @@
+#![feature(associated_type_defaults)]
+
+// This is a partial regression test for #26681, which used to fail to resolve
+// `Self` in the assoc. constant, and now fails with a type mismatch because
+// `Self::Fv` cannot be assumed to equal `u8` inside the trait.
+
+trait Foo {
+ type Bar;
+}
+
+impl Foo for u8 {
+ type Bar = ();
+}
+
+trait Baz {
+ type Fv: Foo = u8;
+ const C: <Self::Fv as Foo>::Bar = 6665; //~ error: mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-26681.stderr b/src/test/ui/associated-types/issue-26681.stderr
new file mode 100644
index 000000000..74411008c
--- /dev/null
+++ b/src/test/ui/associated-types/issue-26681.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-26681.rs:17:39
+ |
+LL | const C: <Self::Fv as Foo>::Bar = 6665;
+ | ^^^^ expected associated type, found integer
+ |
+ = note: expected associated type `<<Self as Baz>::Fv as Foo>::Bar`
+ found type `{integer}`
+ = help: consider constraining the associated type `<<Self as Baz>::Fv as Foo>::Bar` to `{integer}`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.rs b/src/test/ui/associated-types/issue-27675-unchecked-bounds.rs
new file mode 100644
index 000000000..1cfc23045
--- /dev/null
+++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.rs
@@ -0,0 +1,19 @@
+/// The compiler previously did not properly check the bound of `From` when it was used from type
+/// of the dyn trait object (use in `copy_any` below). Since the associated type is under user
+/// control in this usage, the compiler could be tricked to believe any type implemented any trait.
+/// This would ICE, except for pure marker traits like `Copy`. It did not require providing an
+/// instance of the dyn trait type, only name said type.
+trait Setup {
+ type From: Copy;
+}
+
+fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
+ *from
+}
+
+pub fn copy_any<T>(t: &T) -> T {
+ copy::<dyn Setup<From=T>>(t)
+ //~^ ERROR the trait bound `T: Copy` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
new file mode 100644
index 000000000..22daaf329
--- /dev/null
+++ b/src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/issue-27675-unchecked-bounds.rs:15:31
+ |
+LL | copy::<dyn Setup<From=T>>(t)
+ | ------------------------- ^ the trait `Copy` is not implemented for `T`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `copy`
+ --> $DIR/issue-27675-unchecked-bounds.rs:10:12
+ |
+LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From {
+ | ^^^^^ required by this bound in `copy`
+help: consider restricting type parameter `T`
+ |
+LL | pub fn copy_any<T: std::marker::Copy>(t: &T) -> T {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-28871.rs b/src/test/ui/associated-types/issue-28871.rs
new file mode 100644
index 000000000..210c783de
--- /dev/null
+++ b/src/test/ui/associated-types/issue-28871.rs
@@ -0,0 +1,24 @@
+// check-pass
+// Regression test for #28871. The problem is that rustc encountered
+// two ways to project, one from a where clause and one from the where
+// clauses on the trait definition. (In fact, in this case, the where
+// clauses originated from the trait definition as well.) The true
+// cause of the error is that the trait definition where clauses are
+// not being normalized, and hence the two sources are considered in
+// conflict, and not a duplicate. Hacky solution is to prefer where
+// clauses over the data found in the trait definition.
+
+trait T {
+ type T;
+}
+
+struct S;
+impl T for S {
+ type T = S;
+}
+
+trait T2 {
+ type T: Iterator<Item=<S as T>::T>;
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/issue-31597.rs b/src/test/ui/associated-types/issue-31597.rs
new file mode 100644
index 000000000..2872be6d6
--- /dev/null
+++ b/src/test/ui/associated-types/issue-31597.rs
@@ -0,0 +1,29 @@
+// check-pass
+#![allow(dead_code)]
+trait Make {
+ type Out;
+
+ fn make() -> Self::Out;
+}
+
+impl Make for () {
+ type Out = ();
+
+ fn make() -> Self::Out {}
+}
+
+// Also make sure we don't hit an ICE when the projection can't be known
+fn f<T: Make>() -> <T as Make>::Out { loop {} }
+
+// ...and that it works with a blanket impl
+trait Tr {
+ type Assoc;
+}
+
+impl<T: Make> Tr for T {
+ type Assoc = ();
+}
+
+fn g<T: Make>() -> <T as Tr>::Assoc { }
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-32350.rs b/src/test/ui/associated-types/issue-32350.rs
new file mode 100644
index 000000000..bda21eb0e
--- /dev/null
+++ b/src/test/ui/associated-types/issue-32350.rs
@@ -0,0 +1,29 @@
+// check-pass
+
+// This is another instance of the "normalizations don't work" issue with
+// defaulted associated types.
+
+#![feature(associated_type_defaults)]
+
+pub trait Emitter<'a> {
+ type Ctxt: 'a;
+ type CtxtBrw: 'a = &'a Self::Ctxt;
+
+ fn get_cx(&'a self) -> Self::CtxtBrw;
+}
+
+struct MyCtxt;
+
+struct MyEmitter {
+ ctxt: MyCtxt
+}
+
+impl <'a> Emitter<'a> for MyEmitter {
+ type Ctxt = MyCtxt;
+
+ fn get_cx(&'a self) -> &'a MyCtxt {
+ &self.ctxt
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-36499.rs b/src/test/ui/associated-types/issue-36499.rs
new file mode 100644
index 000000000..7f8f13ef8
--- /dev/null
+++ b/src/test/ui/associated-types/issue-36499.rs
@@ -0,0 +1,5 @@
+// error-pattern: aborting due to previous error
+
+fn main() {
+ 2 + +2;
+}
diff --git a/src/test/ui/associated-types/issue-36499.stderr b/src/test/ui/associated-types/issue-36499.stderr
new file mode 100644
index 000000000..80e42b61d
--- /dev/null
+++ b/src/test/ui/associated-types/issue-36499.stderr
@@ -0,0 +1,14 @@
+error: leading `+` is not supported
+ --> $DIR/issue-36499.rs:4:9
+ |
+LL | 2 + +2;
+ | ^ unexpected `+`
+ |
+help: try removing the `+`
+ |
+LL - 2 + +2;
+LL + 2 + 2;
+ |
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/issue-37808.rs b/src/test/ui/associated-types/issue-37808.rs
new file mode 100644
index 000000000..3701c37d0
--- /dev/null
+++ b/src/test/ui/associated-types/issue-37808.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+trait Parent {
+ type Ty;
+ type Assoc: Child<Self::Ty>;
+}
+
+trait Child<T> {}
+
+struct ChildWrapper<T>(T);
+impl<A, T> Child<A> for ChildWrapper<T> where T: Child<A> {}
+
+struct ParentWrapper<T>(T);
+impl<A, T: Parent<Ty = A>> Parent for ParentWrapper<T> {
+ type Ty = A;
+ type Assoc = ChildWrapper<T::Assoc>;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-37883.rs b/src/test/ui/associated-types/issue-37883.rs
new file mode 100644
index 000000000..d854f6af3
--- /dev/null
+++ b/src/test/ui/associated-types/issue-37883.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+use std::ops::Mul;
+
+fn main() {}
+
+trait Ring {}
+trait Real: Ring {}
+
+trait Module: Sized + Mul<<Self as Module>::Ring, Output = Self> {
+ type Ring: Ring;
+}
+
+trait EuclideanSpace {
+ type Coordinates: Module<Ring = Self::Real>;
+ type Real: Real;
+}
+
+trait Translation<E: EuclideanSpace> {
+ fn to_vector(&self) -> E::Coordinates;
+
+ fn powf(&self, n: <E::Coordinates as Module>::Ring) -> E::Coordinates {
+ self.to_vector() * n
+ }
+}
diff --git a/src/test/ui/associated-types/issue-38917.rs b/src/test/ui/associated-types/issue-38917.rs
new file mode 100644
index 000000000..7e898851a
--- /dev/null
+++ b/src/test/ui/associated-types/issue-38917.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+use std::borrow::Borrow;
+
+trait TNode: Sized {
+ type ConcreteElement: TElement<ConcreteNode = Self>;
+}
+
+trait TElement: Sized {
+ type ConcreteNode: TNode<ConcreteElement = Self>;
+}
+
+trait DomTraversal<N: TNode> {
+ type BorrowElement: Borrow<N::ConcreteElement>;
+}
+
+#[allow(dead_code)]
+fn recalc_style_at<E, D>()
+where
+ E: TElement,
+ D: DomTraversal<E::ConcreteNode>,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-39532.rs b/src/test/ui/associated-types/issue-39532.rs
new file mode 100644
index 000000000..52652cede
--- /dev/null
+++ b/src/test/ui/associated-types/issue-39532.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#![allow(unused)]
+
+trait Foo {
+ type Bar;
+ type Baz: Bar<Self::Bar>;
+}
+
+trait Bar<T> {}
+
+fn x<T: Foo<Bar = U>, U>(t: &T) {}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-40093.rs b/src/test/ui/associated-types/issue-40093.rs
new file mode 100644
index 000000000..fd325ae10
--- /dev/null
+++ b/src/test/ui/associated-types/issue-40093.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+pub trait Test {
+ type Item;
+ type Bundle: From<Self::Item>;
+}
+
+fn fails<T>()
+where
+ T: Test<Item = String>,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-41868.rs b/src/test/ui/associated-types/issue-41868.rs
new file mode 100644
index 000000000..52bbd1f5d
--- /dev/null
+++ b/src/test/ui/associated-types/issue-41868.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+// Defaulted assoc. types should normalize properly in impls that don't
+// override them.
+
+#![feature(associated_type_defaults)]
+
+pub struct Foo;
+
+pub trait CanDecode: Sized {
+ type Output = Self;
+ fn read(rdr: &mut Foo) -> Option<Self::Output>;
+}
+
+impl CanDecode for u8 {
+ fn read(rdr: &mut Foo) -> Option<Self::Output> { Some(42) }
+}
+
+impl CanDecode for u16 {
+ fn read(rdr: &mut Foo) -> Option<u16> { Some(17) }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-43475.rs b/src/test/ui/associated-types/issue-43475.rs
new file mode 100644
index 000000000..5f177333c
--- /dev/null
+++ b/src/test/ui/associated-types/issue-43475.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+trait Foo { type FooT: Foo; }
+impl Foo for () { type FooT = (); }
+trait Bar<T: Foo> { type BarT: Bar<T::FooT>; }
+impl Bar<()> for () { type BarT = (); }
+
+#[allow(dead_code)]
+fn test<C: Bar<()>>() { }
+fn main() { }
diff --git a/src/test/ui/associated-types/issue-43784-associated-type.rs b/src/test/ui/associated-types/issue-43784-associated-type.rs
new file mode 100644
index 000000000..78815d8d3
--- /dev/null
+++ b/src/test/ui/associated-types/issue-43784-associated-type.rs
@@ -0,0 +1,17 @@
+pub trait Partial<X: ?Sized>: Copy {
+}
+
+pub trait Complete {
+ type Assoc: Partial<Self>;
+}
+
+impl<T> Partial<T> for T::Assoc where
+ T: Complete
+{
+}
+
+impl<T> Complete for T {
+ type Assoc = T; //~ ERROR the trait bound `T: Copy` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-43784-associated-type.stderr b/src/test/ui/associated-types/issue-43784-associated-type.stderr
new file mode 100644
index 000000000..f1677b822
--- /dev/null
+++ b/src/test/ui/associated-types/issue-43784-associated-type.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Copy` is not satisfied
+ --> $DIR/issue-43784-associated-type.rs:14:18
+ |
+LL | type Assoc = T;
+ | ^ the trait `Copy` is not implemented for `T`
+ |
+note: required by a bound in `Complete::Assoc`
+ --> $DIR/issue-43784-associated-type.rs:5:17
+ |
+LL | type Assoc: Partial<Self>;
+ | ^^^^^^^^^^^^^ required by this bound in `Complete::Assoc`
+help: consider restricting type parameter `T`
+ |
+LL | impl<T: std::marker::Copy> Complete for T {
+ | +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-43924.rs b/src/test/ui/associated-types/issue-43924.rs
new file mode 100644
index 000000000..6a63b3e09
--- /dev/null
+++ b/src/test/ui/associated-types/issue-43924.rs
@@ -0,0 +1,16 @@
+#![feature(associated_type_defaults)]
+
+// This used to cause an ICE because assoc. type defaults weren't properly
+// type-checked.
+
+trait Foo<T: Default + ToString> {
+ type Out: Default + ToString + ?Sized = dyn ToString; //~ ERROR not satisfied
+}
+
+impl Foo<u32> for () {}
+impl Foo<u64> for () {}
+
+fn main() {
+ assert_eq!(<() as Foo<u32>>::Out::default().to_string(), "false");
+ //~^ ERROR no function or associated item named `default` found for trait object
+}
diff --git a/src/test/ui/associated-types/issue-43924.stderr b/src/test/ui/associated-types/issue-43924.stderr
new file mode 100644
index 000000000..526f425b2
--- /dev/null
+++ b/src/test/ui/associated-types/issue-43924.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `(dyn ToString + 'static): Default` is not satisfied
+ --> $DIR/issue-43924.rs:7:45
+ |
+LL | type Out: Default + ToString + ?Sized = dyn ToString;
+ | ^^^^^^^^^^^^ the trait `Default` is not implemented for `(dyn ToString + 'static)`
+ |
+note: required by a bound in `Foo::Out`
+ --> $DIR/issue-43924.rs:7:15
+ |
+LL | type Out: Default + ToString + ?Sized = dyn ToString;
+ | ^^^^^^^ required by this bound in `Foo::Out`
+
+error[E0599]: no function or associated item named `default` found for trait object `(dyn ToString + 'static)` in the current scope
+ --> $DIR/issue-43924.rs:14:39
+ |
+LL | assert_eq!(<() as Foo<u32>>::Out::default().to_string(), "false");
+ | ^^^^^^^ function or associated item not found in `(dyn ToString + 'static)`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-44153.rs b/src/test/ui/associated-types/issue-44153.rs
new file mode 100644
index 000000000..2101cb61a
--- /dev/null
+++ b/src/test/ui/associated-types/issue-44153.rs
@@ -0,0 +1,19 @@
+pub trait Array {
+ type Element;
+}
+
+pub trait Visit {
+ fn visit() {}
+}
+
+impl Array for () {
+ type Element = ();
+}
+
+impl<'a> Visit for () where
+ (): Array<Element=&'a ()>,
+{}
+
+fn main() {
+ <() as Visit>::visit(); //~ ERROR: type mismatch resolving
+}
diff --git a/src/test/ui/associated-types/issue-44153.stderr b/src/test/ui/associated-types/issue-44153.stderr
new file mode 100644
index 000000000..200efbe02
--- /dev/null
+++ b/src/test/ui/associated-types/issue-44153.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
+ --> $DIR/issue-44153.rs:18:5
+ |
+LL | <() as Visit>::visit();
+ | ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Array>::Element == &()`
+ |
+note: expected this to be `&()`
+ --> $DIR/issue-44153.rs:10:20
+ |
+LL | type Element = ();
+ | ^^
+note: required because of the requirements on the impl of `Visit` for `()`
+ --> $DIR/issue-44153.rs:13:10
+ |
+LL | impl<'a> Visit for () where
+ | ^^^^^ ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/issue-47139-1.rs b/src/test/ui/associated-types/issue-47139-1.rs
new file mode 100644
index 000000000..c55fc3434
--- /dev/null
+++ b/src/test/ui/associated-types/issue-47139-1.rs
@@ -0,0 +1,78 @@
+// run-pass
+// Regression test for issue #47139:
+//
+// Coherence was encountering an (unnecessary) overflow trying to
+// decide if the two impls of dummy overlap.
+//
+// The overflow went something like:
+//
+// - `&'a ?T: Insertable` ?
+// - let ?T = Option<?U> ?
+// - `Option<?U>: Insertable` ?
+// - `Option<&'a ?U>: Insertable` ?
+// - `&'a ?U: Insertable` ?
+//
+// While somewhere in the middle, a projection would occur, which
+// broke cycle detection.
+//
+// It turned out that this cycle was being kicked off due to some
+// extended diagnostic attempts in coherence, so removing those
+// sidestepped the issue for now.
+
+#![allow(dead_code)]
+
+pub trait Insertable {
+ type Values;
+
+ fn values(self) -> Self::Values;
+}
+
+impl<T> Insertable for Option<T>
+ where
+ T: Insertable,
+ T::Values: Default,
+{
+ type Values = T::Values;
+
+ fn values(self) -> Self::Values {
+ self.map(Insertable::values).unwrap_or_default()
+ }
+}
+
+impl<'a, T> Insertable for &'a Option<T>
+ where
+ Option<&'a T>: Insertable,
+{
+ type Values = <Option<&'a T> as Insertable>::Values;
+
+ fn values(self) -> Self::Values {
+ self.as_ref().values()
+ }
+}
+
+impl<'a, T> Insertable for &'a [T]
+{
+ type Values = Self;
+
+ fn values(self) -> Self::Values {
+ self
+ }
+}
+
+trait Unimplemented { }
+
+trait Dummy { }
+
+struct Foo<T> { t: T }
+
+impl<'a, U> Dummy for Foo<&'a U>
+ where &'a U: Insertable
+{
+}
+
+impl<T> Dummy for T
+ where T: Unimplemented
+{ }
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/issue-47139-2.rs b/src/test/ui/associated-types/issue-47139-2.rs
new file mode 100644
index 000000000..d2ef89425
--- /dev/null
+++ b/src/test/ui/associated-types/issue-47139-2.rs
@@ -0,0 +1,66 @@
+// run-pass
+// Regression test for issue #47139:
+//
+// Same as issue-47139-1.rs, but the impls of dummy are in the
+// opposite order. This influenced the way that coherence ran and in
+// some cases caused the overflow to occur when it wouldn't otherwise.
+// In an effort to make the regr test more robust, I am including both
+// orderings.
+
+#![allow(dead_code)]
+
+pub trait Insertable {
+ type Values;
+
+ fn values(self) -> Self::Values;
+}
+
+impl<T> Insertable for Option<T>
+ where
+ T: Insertable,
+ T::Values: Default,
+{
+ type Values = T::Values;
+
+ fn values(self) -> Self::Values {
+ self.map(Insertable::values).unwrap_or_default()
+ }
+}
+
+impl<'a, T> Insertable for &'a Option<T>
+ where
+ Option<&'a T>: Insertable,
+{
+ type Values = <Option<&'a T> as Insertable>::Values;
+
+ fn values(self) -> Self::Values {
+ self.as_ref().values()
+ }
+}
+
+impl<'a, T> Insertable for &'a [T]
+{
+ type Values = Self;
+
+ fn values(self) -> Self::Values {
+ self
+ }
+}
+
+trait Unimplemented { }
+
+trait Dummy { }
+
+struct Foo<T> { t: T }
+
+impl<T> Dummy for T
+ where T: Unimplemented
+{ }
+
+impl<'a, U> Dummy for Foo<&'a U>
+ where &'a U: Insertable
+{
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/issue-47385.rs b/src/test/ui/associated-types/issue-47385.rs
new file mode 100644
index 000000000..d43d674e9
--- /dev/null
+++ b/src/test/ui/associated-types/issue-47385.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(associated_type_defaults)]
+
+pub struct Foo;
+
+pub trait Bar: From<<Self as Bar>::Input> {
+ type Input = Self;
+}
+
+impl Bar for Foo {
+ // Will compile with explicit type:
+ // type Input = Self;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-47814.rs b/src/test/ui/associated-types/issue-47814.rs
new file mode 100644
index 000000000..90e8a3bc2
--- /dev/null
+++ b/src/test/ui/associated-types/issue-47814.rs
@@ -0,0 +1,13 @@
+struct ArpIPv4<'a> {
+ s: &'a u8
+}
+
+impl<'a> ArpIPv4<'a> {
+ const LENGTH: usize = 20;
+
+ pub fn to_buffer() -> [u8; Self::LENGTH] { //~ ERROR generic `Self` types are currently not permitted in anonymous constants
+ unimplemented!()
+ }
+}
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/issue-47814.stderr b/src/test/ui/associated-types/issue-47814.stderr
new file mode 100644
index 000000000..2e4ddb811
--- /dev/null
+++ b/src/test/ui/associated-types/issue-47814.stderr
@@ -0,0 +1,14 @@
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/issue-47814.rs:8:32
+ |
+LL | pub fn to_buffer() -> [u8; Self::LENGTH] {
+ | ^^^^
+ |
+note: not a concrete type
+ --> $DIR/issue-47814.rs:5:10
+ |
+LL | impl<'a> ArpIPv4<'a> {
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/issue-48010.rs b/src/test/ui/associated-types/issue-48010.rs
new file mode 100644
index 000000000..70e30c132
--- /dev/null
+++ b/src/test/ui/associated-types/issue-48010.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![crate_type = "lib"]
+
+pub struct Foo;
+
+pub struct Path<T: Bar> {
+ _inner: T::Slice,
+}
+
+pub trait Bar: Sized {
+ type Slice: ?Sized;
+
+ fn open(_: &Path<Self>);
+}
+
+impl Bar for Foo {
+ type Slice = [u8];
+
+ fn open(_: &Path<Self>) {
+ unimplemented!()
+ }
+}
diff --git a/src/test/ui/associated-types/issue-48551.rs b/src/test/ui/associated-types/issue-48551.rs
new file mode 100644
index 000000000..b95a4832b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-48551.rs
@@ -0,0 +1,34 @@
+// check-pass
+// Regression test for #48551. Covers a case where duplicate candidates
+// arose during associated type projection.
+
+use std::ops::{Mul, MulAssign};
+
+pub trait ClosedMul<Right>: Sized + Mul<Right, Output = Self> + MulAssign<Right> {}
+impl<T, Right> ClosedMul<Right> for T
+where
+ T: Mul<Right, Output = T> + MulAssign<Right>,
+{
+}
+
+pub trait InnerSpace: ClosedMul<<Self as InnerSpace>::Real> {
+ type Real;
+}
+
+pub trait FiniteDimVectorSpace: ClosedMul<<Self as FiniteDimVectorSpace>::Field> {
+ type Field;
+}
+
+pub trait FiniteDimInnerSpace
+ : InnerSpace + FiniteDimVectorSpace<Field = <Self as InnerSpace>::Real> {
+}
+
+pub trait EuclideanSpace: ClosedMul<<Self as EuclideanSpace>::Real> {
+ type Coordinates: FiniteDimInnerSpace<Real = Self::Real>
+ + Mul<Self::Real, Output = Self::Coordinates>
+ + MulAssign<Self::Real>;
+
+ type Real;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-50301.rs b/src/test/ui/associated-types/issue-50301.rs
new file mode 100644
index 000000000..47ee3e7ad
--- /dev/null
+++ b/src/test/ui/associated-types/issue-50301.rs
@@ -0,0 +1,31 @@
+// Tests that HRTBs are correctly accepted -- https://github.com/rust-lang/rust/issues/50301
+// check-pass
+trait Trait
+where
+ for<'a> &'a Self::IntoIter: IntoIterator<Item = u32>,
+{
+ type IntoIter;
+ fn get(&self) -> Self::IntoIter;
+}
+
+struct Impl(Vec<u32>);
+
+impl Trait for Impl {
+ type IntoIter = ImplIntoIter;
+ fn get(&self) -> Self::IntoIter {
+ ImplIntoIter(self.0.clone())
+ }
+}
+
+struct ImplIntoIter(Vec<u32>);
+
+impl<'a> IntoIterator for &'a ImplIntoIter {
+ type Item = <Self::IntoIter as Iterator>::Item;
+ type IntoIter = std::iter::Cloned<std::slice::Iter<'a, u32>>;
+ fn into_iter(self) -> Self::IntoIter {
+ (&self.0).into_iter().cloned()
+ }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/associated-types/issue-54108.rs b/src/test/ui/associated-types/issue-54108.rs
new file mode 100644
index 000000000..87f67ce4b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-54108.rs
@@ -0,0 +1,41 @@
+use std::ops::Add;
+
+pub trait Encoder {
+ type Size: Add<Output = Self::Size>;
+
+ fn foo(&self) -> Self::Size;
+}
+
+pub trait SubEncoder: Encoder {
+ type ActualSize;
+
+ fn bar(&self) -> Self::Size;
+}
+
+impl<T> Encoder for T
+where
+ T: SubEncoder,
+{
+ type Size = <Self as SubEncoder>::ActualSize;
+ //~^ ERROR: cannot add `<T as SubEncoder>::ActualSize` to `<T as SubEncoder>::ActualSize`
+
+ fn foo(&self) -> Self::Size {
+ self.bar() + self.bar()
+ }
+}
+
+pub struct UnitEncoder;
+
+impl SubEncoder for UnitEncoder {
+ type ActualSize = ();
+
+ fn bar(&self) {}
+}
+
+pub fn fun<R: Encoder>(encoder: &R) {
+ encoder.foo();
+}
+
+fn main() {
+ fun(&UnitEncoder {});
+}
diff --git a/src/test/ui/associated-types/issue-54108.stderr b/src/test/ui/associated-types/issue-54108.stderr
new file mode 100644
index 000000000..6ff5e4542
--- /dev/null
+++ b/src/test/ui/associated-types/issue-54108.stderr
@@ -0,0 +1,20 @@
+error[E0277]: cannot add `<T as SubEncoder>::ActualSize` to `<T as SubEncoder>::ActualSize`
+ --> $DIR/issue-54108.rs:19:17
+ |
+LL | type Size = <Self as SubEncoder>::ActualSize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `<T as SubEncoder>::ActualSize + <T as SubEncoder>::ActualSize`
+ |
+ = help: the trait `Add` is not implemented for `<T as SubEncoder>::ActualSize`
+note: required by a bound in `Encoder::Size`
+ --> $DIR/issue-54108.rs:4:16
+ |
+LL | type Size: Add<Output = Self::Size>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size`
+help: consider further restricting the associated type
+ |
+LL | T: SubEncoder, <T as SubEncoder>::ActualSize: Add
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-54182-1.rs b/src/test/ui/associated-types/issue-54182-1.rs
new file mode 100644
index 000000000..1a1e98cba
--- /dev/null
+++ b/src/test/ui/associated-types/issue-54182-1.rs
@@ -0,0 +1,92 @@
+// run-pass
+
+// Tests that the return type of trait methods is correctly normalized when
+// checking that a method in an impl matches the trait definition when the
+// return type involves a defaulted associated type.
+// ie. the trait has a method with return type `-> Self::R`, and `type R = ()`,
+// but the impl leaves out the return type (resulting in `()`).
+// Note that specialization is not involved in this test; no items in
+// implementations may be overridden. If they were, the normalization wouldn't
+// happen.
+
+#![feature(associated_type_defaults)]
+
+macro_rules! overload {
+ ($a:expr, $b:expr) => {
+ overload::overload2($a, $b)
+ };
+ ($a:expr, $b:expr, $c:expr) => {
+ overload::overload3($a, $b, $c)
+ }
+}
+
+fn main() {
+ let () = overload!(42, true);
+
+ let r: f32 = overload!("Hello world", 13.0);
+ assert_eq!(r, 13.0);
+
+ let () = overload!(42, true, 42.5);
+
+ let r: i32 = overload!("Hello world", 13.0, 42);
+ assert_eq!(r, 42);
+}
+
+mod overload {
+ /// This trait has an assoc. type defaulting to `()`, and a required method returning a value
+ /// of that assoc. type.
+ pub trait Overload {
+ // type R;
+ type R = ();
+ fn overload(self) -> Self::R;
+ }
+
+ // overloads for 2 args
+ impl Overload for (i32, bool) {
+ // type R = ();
+
+ /// This function has no return type specified, and so defaults to `()`.
+ ///
+ /// This should work, but didn't, until RFC 2532 was implemented.
+ fn overload(self) /*-> Self::R*/ {
+ let (a, b) = self; // destructure args
+ println!("i32 and bool {:?}", (a, b));
+ }
+ }
+ impl<'a> Overload for (&'a str, f32) {
+ type R = f32;
+ fn overload(self) -> Self::R {
+ let (a, b) = self; // destructure args
+ println!("&str and f32 {:?}", (a, b));
+ b
+ }
+ }
+
+ // overloads for 3 args
+ impl Overload for (i32, bool, f32) {
+ // type R = ();
+ fn overload(self) /*-> Self::R*/ {
+ let (a, b, c) = self; // destructure args
+ println!("i32 and bool and f32 {:?}", (a, b, c));
+ }
+ }
+ impl<'a> Overload for (&'a str, f32, i32) {
+ type R = i32;
+ fn overload(self) -> Self::R {
+ let (a, b, c) = self; // destructure args
+ println!("&str and f32 and i32: {:?}", (a, b, c));
+ c
+ }
+ }
+
+ // overloads for more args
+ // ...
+
+ pub fn overload2<R, A, B>(a: A, b: B) -> R where (A, B): Overload<R = R> {
+ (a, b).overload()
+ }
+
+ pub fn overload3<R, A, B, C>(a: A, b: B, c: C) -> R where (A, B, C): Overload<R = R> {
+ (a, b, c).overload()
+ }
+}
diff --git a/src/test/ui/associated-types/issue-54182-2.rs b/src/test/ui/associated-types/issue-54182-2.rs
new file mode 100644
index 000000000..c88c76631
--- /dev/null
+++ b/src/test/ui/associated-types/issue-54182-2.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+// Before RFC 2532, normalizing a defaulted assoc. type didn't work at all,
+// unless the impl in question overrides that type, which makes the default
+// pointless.
+
+#![feature(associated_type_defaults)]
+
+trait Tr {
+ type Assoc = ();
+}
+
+impl Tr for () {}
+
+fn f(thing: <() as Tr>::Assoc) {
+ let c: () = thing;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-54467.rs b/src/test/ui/associated-types/issue-54467.rs
new file mode 100644
index 000000000..734bf2768
--- /dev/null
+++ b/src/test/ui/associated-types/issue-54467.rs
@@ -0,0 +1,46 @@
+// run-pass
+
+pub trait Stream {
+ type Item;
+ type Error;
+}
+
+pub trait ParseError<I> {
+ type Output;
+}
+
+impl ParseError<char> for u32 {
+ type Output = ();
+}
+
+impl Stream for () {
+ type Item = char;
+ type Error = u32;
+}
+
+pub struct Lex<'a, I>
+ where I: Stream,
+ I::Error: ParseError<char>,
+ <<I as Stream>::Error as ParseError<char>>::Output: 'a
+{
+ x: &'a <I::Error as ParseError<char>>::Output
+}
+
+pub struct Reserved<'a, I> where
+ I: Stream<Item=char> + 'a,
+ I::Error: ParseError<I::Item>,
+ <<I as Stream>::Error as ParseError<char>>::Output: 'a
+
+{
+ x: Lex<'a, I>
+}
+
+fn main() {
+ let r: Reserved<()> = Reserved {
+ x: Lex {
+ x: &()
+ }
+ };
+
+ let _v = r.x.x;
+}
diff --git a/src/test/ui/associated-types/issue-55846.rs b/src/test/ui/associated-types/issue-55846.rs
new file mode 100644
index 000000000..bd7667523
--- /dev/null
+++ b/src/test/ui/associated-types/issue-55846.rs
@@ -0,0 +1,39 @@
+// run-pass
+
+// Regression test for #55846, which once caused an ICE.
+
+use std::marker::PhantomData;
+
+struct Foo;
+
+struct Bar<A> {
+ a: PhantomData<A>,
+}
+
+impl Fooifier for Foo {
+ type Assoc = Foo;
+}
+
+trait Fooifier {
+ type Assoc;
+}
+
+trait Barifier<H> {
+ fn barify();
+}
+
+impl<H> Barifier<H> for Bar<H> {
+ fn barify() {
+ println!("All correct!");
+ }
+}
+
+impl Bar<<Foo as Fooifier>::Assoc> {
+ fn this_shouldnt_crash() {
+ <Self as Barifier<<Foo as Fooifier>::Assoc>>::barify();
+ }
+}
+
+fn main() {
+ Bar::<Foo>::this_shouldnt_crash();
+}
diff --git a/src/test/ui/associated-types/issue-59324.rs b/src/test/ui/associated-types/issue-59324.rs
new file mode 100644
index 000000000..162f9e00e
--- /dev/null
+++ b/src/test/ui/associated-types/issue-59324.rs
@@ -0,0 +1,26 @@
+trait NotFoo {}
+
+pub trait Foo: NotFoo {
+ type OnlyFoo;
+}
+
+pub trait Service {
+ type AssocType;
+}
+
+pub trait ThriftService<Bug: NotFoo>:
+//~^ ERROR the trait bound `Bug: Foo` is not satisfied
+//~| ERROR the trait bound `Bug: Foo` is not satisfied
+ Service<AssocType = <Bug as Foo>::OnlyFoo>
+{
+ fn get_service(
+ //~^ ERROR the trait bound `Bug: Foo` is not satisfied
+ &self,
+ ) -> Self::AssocType;
+ //~^ the trait bound `Bug: Foo` is not satisfied
+}
+
+fn with_factory<H>(factory: dyn ThriftService<()>) {}
+//~^ ERROR the trait bound `(): Foo` is not satisfied
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr
new file mode 100644
index 000000000..a84b599b5
--- /dev/null
+++ b/src/test/ui/associated-types/issue-59324.stderr
@@ -0,0 +1,65 @@
+error[E0277]: the trait bound `Bug: Foo` is not satisfied
+ --> $DIR/issue-59324.rs:11:1
+ |
+LL | / pub trait ThriftService<Bug: NotFoo>:
+LL | |
+LL | |
+LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
+ | |______________________________________________^ the trait `Foo` is not implemented for `Bug`
+ |
+help: consider further restricting this bound
+ |
+LL | pub trait ThriftService<Bug: NotFoo + Foo>:
+ | +++++
+
+error[E0277]: the trait bound `Bug: Foo` is not satisfied
+ --> $DIR/issue-59324.rs:11:1
+ |
+LL | / pub trait ThriftService<Bug: NotFoo>:
+LL | |
+LL | |
+LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
+... |
+LL | |
+LL | | }
+ | |_^ the trait `Foo` is not implemented for `Bug`
+ |
+help: consider further restricting this bound
+ |
+LL | pub trait ThriftService<Bug: NotFoo + Foo>:
+ | +++++
+
+error[E0277]: the trait bound `Bug: Foo` is not satisfied
+ --> $DIR/issue-59324.rs:16:5
+ |
+LL | / fn get_service(
+LL | |
+LL | | &self,
+LL | | ) -> Self::AssocType;
+ | |_________________________^ the trait `Foo` is not implemented for `Bug`
+ |
+help: consider further restricting this bound
+ |
+LL | pub trait ThriftService<Bug: NotFoo + Foo>:
+ | +++++
+
+error[E0277]: the trait bound `(): Foo` is not satisfied
+ --> $DIR/issue-59324.rs:23:29
+ |
+LL | fn with_factory<H>(factory: dyn ThriftService<()>) {}
+ | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
+
+error[E0277]: the trait bound `Bug: Foo` is not satisfied
+ --> $DIR/issue-59324.rs:19:10
+ |
+LL | ) -> Self::AssocType;
+ | ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
+ |
+help: consider further restricting this bound
+ |
+LL | pub trait ThriftService<Bug: NotFoo + Foo>:
+ | +++++
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-62200.rs b/src/test/ui/associated-types/issue-62200.rs
new file mode 100644
index 000000000..9d18690e9
--- /dev/null
+++ b/src/test/ui/associated-types/issue-62200.rs
@@ -0,0 +1,15 @@
+struct S {}
+
+trait T<'a> {
+ type A;
+}
+
+impl T<'_> for S {
+ type A = u32;
+}
+
+fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
+//~^ ERROR binding for associated type `Output` references an anonymous lifetime
+//~^^ NOTE lifetimes appearing in an associated type are not considered constrained
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-62200.stderr b/src/test/ui/associated-types/issue-62200.stderr
new file mode 100644
index 000000000..f14cd81fd
--- /dev/null
+++ b/src/test/ui/associated-types/issue-62200.stderr
@@ -0,0 +1,11 @@
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+ --> $DIR/issue-62200.rs:11:39
+ |
+LL | fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
+ | ^^^^^^^^^^^^^^^
+ |
+ = note: lifetimes appearing in an associated type are not considered constrained
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0582`.
diff --git a/src/test/ui/associated-types/issue-63591.rs b/src/test/ui/associated-types/issue-63591.rs
new file mode 100644
index 000000000..4d2e39f4d
--- /dev/null
+++ b/src/test/ui/associated-types/issue-63591.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+#![feature(associated_type_bounds)]
+#![feature(type_alias_impl_trait)]
+
+fn main() {}
+
+trait Bar { type Assoc; }
+
+trait Thing {
+ type Out;
+ fn func() -> Self::Out;
+}
+
+struct AssocIsCopy;
+impl Bar for AssocIsCopy { type Assoc = u8; }
+
+impl Thing for AssocIsCopy {
+ type Out = impl Bar<Assoc: Copy>;
+
+ fn func() -> Self::Out {
+ AssocIsCopy
+ }
+}
diff --git a/src/test/ui/associated-types/issue-63593.rs b/src/test/ui/associated-types/issue-63593.rs
new file mode 100644
index 000000000..8dbc24c06
--- /dev/null
+++ b/src/test/ui/associated-types/issue-63593.rs
@@ -0,0 +1,13 @@
+#![feature(associated_type_defaults)]
+
+// Tests that `Self` is not assumed to implement `Sized` when used as an
+// associated type default.
+
+trait Inner<S> {}
+
+trait MyTrait {
+ type This = Self; //~ error: size for values of type `Self` cannot be known
+ fn something<I: Inner<Self::This>>(i: I);
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-63593.stderr b/src/test/ui/associated-types/issue-63593.stderr
new file mode 100644
index 000000000..f643ec3ff
--- /dev/null
+++ b/src/test/ui/associated-types/issue-63593.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+ --> $DIR/issue-63593.rs:9:17
+ |
+LL | type This = Self;
+ | ^^^^ doesn't have a size known at compile-time
+ |
+note: required by a bound in `MyTrait::This`
+ --> $DIR/issue-63593.rs:9:5
+ |
+LL | type This = Self;
+ | ^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::This`
+help: consider further restricting `Self`
+ |
+LL | trait MyTrait: Sized {
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-64848.rs b/src/test/ui/associated-types/issue-64848.rs
new file mode 100644
index 000000000..77712168a
--- /dev/null
+++ b/src/test/ui/associated-types/issue-64848.rs
@@ -0,0 +1,29 @@
+// build-pass
+
+trait AssociatedConstant {
+ const DATA: ();
+}
+
+impl<F, T> AssociatedConstant for F
+where
+ F: FnOnce() -> T,
+ T: AssociatedConstant,
+{
+ const DATA: () = T::DATA;
+}
+
+impl AssociatedConstant for () {
+ const DATA: () = ();
+}
+
+fn foo() -> impl AssociatedConstant {
+ ()
+}
+
+fn get_data<T: AssociatedConstant>(_: T) -> &'static () {
+ &T::DATA
+}
+
+fn main() {
+ get_data(foo);
+}
diff --git a/src/test/ui/associated-types/issue-64855-2.rs b/src/test/ui/associated-types/issue-64855-2.rs
new file mode 100644
index 000000000..1d53bd570
--- /dev/null
+++ b/src/test/ui/associated-types/issue-64855-2.rs
@@ -0,0 +1,5 @@
+// check-pass
+
+pub struct Bar<'a>(&'a Self) where Self: ;
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-64855.rs b/src/test/ui/associated-types/issue-64855.rs
new file mode 100644
index 000000000..81cf3ae6e
--- /dev/null
+++ b/src/test/ui/associated-types/issue-64855.rs
@@ -0,0 +1,8 @@
+pub trait Foo {
+ type Type;
+}
+
+pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
+//~^ ERROR the trait bound `Bar<T>: Foo` is not satisfied
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-64855.stderr b/src/test/ui/associated-types/issue-64855.stderr
new file mode 100644
index 000000000..6ad795c11
--- /dev/null
+++ b/src/test/ui/associated-types/issue-64855.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `Bar<T>: Foo` is not satisfied
+ --> $DIR/issue-64855.rs:5:19
+ |
+LL | pub struct Bar<T>(<Self as Foo>::Type) where Self: ;
+ | ^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar<T>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-65774-1.rs b/src/test/ui/associated-types/issue-65774-1.rs
new file mode 100644
index 000000000..934514055
--- /dev/null
+++ b/src/test/ui/associated-types/issue-65774-1.rs
@@ -0,0 +1,58 @@
+#![feature(associated_type_defaults)]
+
+trait MyDisplay { fn method(&self) { } }
+
+impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
+
+struct T;
+
+trait MPU {
+ type MpuConfig: MyDisplay = T;
+ //~^ ERROR the trait bound `T: MyDisplay` is not satisfied
+}
+
+struct S;
+
+impl MPU for S { }
+
+trait MyWrite {
+ fn my_write(&self, _: &dyn MyDisplay) { }
+}
+
+trait ProcessType {
+ fn process_detail_fmt(&self, _: &mut dyn MyWrite);
+}
+
+struct Process;
+
+impl ProcessType for Process {
+ fn process_detail_fmt(&self, writer: &mut dyn MyWrite)
+ {
+
+ let mut val: Option<<S as MPU>::MpuConfig> = None;
+ let valref: &mut <S as MPU>::MpuConfig = val.as_mut().unwrap();
+
+ // // This causes a different ICE (but its similar if you squint right):
+ // //
+ // // `Unimplemented` selecting `Binder(<T as MyDisplay>)` during codegen
+ //
+ // writer.my_write(valref)
+
+ // This one causes the ICE:
+ // FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<T as MyDisplay>)),
+ // depth=1),Unimplemented)
+ let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
+ //~^ ERROR the trait bound `T: MyDisplay` is not satisfied
+ closure(valref);
+ }
+}
+
+fn create() -> &'static dyn ProcessType {
+ let input: Option<&mut Process> = None;
+ let process: &mut Process = input.unwrap();
+ process
+}
+
+pub fn main() {
+ create();
+}
diff --git a/src/test/ui/associated-types/issue-65774-1.stderr b/src/test/ui/associated-types/issue-65774-1.stderr
new file mode 100644
index 000000000..419de689c
--- /dev/null
+++ b/src/test/ui/associated-types/issue-65774-1.stderr
@@ -0,0 +1,30 @@
+error[E0277]: the trait bound `T: MyDisplay` is not satisfied
+ --> $DIR/issue-65774-1.rs:10:33
+ |
+LL | type MpuConfig: MyDisplay = T;
+ | ^ the trait `MyDisplay` is not implemented for `T`
+ |
+ = help: the trait `MyDisplay` is implemented for `&'a mut T`
+note: required by a bound in `MPU::MpuConfig`
+ --> $DIR/issue-65774-1.rs:10:21
+ |
+LL | type MpuConfig: MyDisplay = T;
+ | ^^^^^^^^^ required by this bound in `MPU::MpuConfig`
+
+error[E0277]: the trait bound `T: MyDisplay` is not satisfied
+ --> $DIR/issue-65774-1.rs:44:76
+ |
+LL | let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
+ | ^^^^^^^ the trait `MyDisplay` is not implemented for `T`
+ |
+ = help: the trait `MyDisplay` is implemented for `&'a mut T`
+note: required because of the requirements on the impl of `MyDisplay` for `&mut T`
+ --> $DIR/issue-65774-1.rs:5:24
+ |
+LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
+ | ^^^^^^^^^ ^^^^^^^^^
+ = note: required for the cast from `&mut T` to the object type `dyn MyDisplay`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-65774-2.rs b/src/test/ui/associated-types/issue-65774-2.rs
new file mode 100644
index 000000000..171e0893b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-65774-2.rs
@@ -0,0 +1,58 @@
+#![feature(associated_type_defaults)]
+
+trait MyDisplay { fn method(&self) { } }
+
+impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
+
+struct T;
+
+trait MPU {
+ type MpuConfig: MyDisplay = T;
+ //~^ ERROR the trait bound `T: MyDisplay` is not satisfied
+}
+
+struct S;
+
+impl MPU for S { }
+
+trait MyWrite {
+ fn my_write(&self, _: &dyn MyDisplay) { }
+}
+
+trait ProcessType {
+ fn process_detail_fmt(&self, _: &mut dyn MyWrite);
+}
+
+struct Process;
+
+impl ProcessType for Process {
+ fn process_detail_fmt(&self, writer: &mut dyn MyWrite)
+ {
+
+ let mut val: Option<<S as MPU>::MpuConfig> = None;
+ let valref: &mut <S as MPU>::MpuConfig = val.as_mut().unwrap();
+
+ // // This causes a different ICE (but its similar if you squint right):
+ // //
+ // // `Unimplemented` selecting `Binder(<T as MyDisplay>)` during codegen
+ //
+ writer.my_write(valref)
+ //~^ ERROR the trait bound `T: MyDisplay` is not satisfied
+
+ // This one causes the ICE:
+ // FulfillmentError(Obligation(predicate=Binder(TraitPredicate(<T as MyDisplay>)),
+ // depth=1),Unimplemented)
+ /*let closure = |config: &mut <S as MPU>::MpuConfig| writer.my_write(&config);
+ closure(valref);*/
+ }
+}
+
+fn create() -> &'static dyn ProcessType {
+ let input: Option<&mut Process> = None;
+ let process: &mut Process = input.unwrap();
+ process
+}
+
+pub fn main() {
+ create();
+}
diff --git a/src/test/ui/associated-types/issue-65774-2.stderr b/src/test/ui/associated-types/issue-65774-2.stderr
new file mode 100644
index 000000000..c22302cdc
--- /dev/null
+++ b/src/test/ui/associated-types/issue-65774-2.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `T: MyDisplay` is not satisfied
+ --> $DIR/issue-65774-2.rs:10:33
+ |
+LL | type MpuConfig: MyDisplay = T;
+ | ^ the trait `MyDisplay` is not implemented for `T`
+ |
+ = help: the trait `MyDisplay` is implemented for `&'a mut T`
+note: required by a bound in `MPU::MpuConfig`
+ --> $DIR/issue-65774-2.rs:10:21
+ |
+LL | type MpuConfig: MyDisplay = T;
+ | ^^^^^^^^^ required by this bound in `MPU::MpuConfig`
+
+error[E0277]: the trait bound `T: MyDisplay` is not satisfied
+ --> $DIR/issue-65774-2.rs:39:25
+ |
+LL | writer.my_write(valref)
+ | ^^^^^^ the trait `MyDisplay` is not implemented for `T`
+ |
+ = help: the trait `MyDisplay` is implemented for `&'a mut T`
+ = note: required for the cast from `T` to the object type `dyn MyDisplay`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/issue-65934.rs b/src/test/ui/associated-types/issue-65934.rs
new file mode 100644
index 000000000..e17b11c5e
--- /dev/null
+++ b/src/test/ui/associated-types/issue-65934.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+trait Trait {
+ type Assoc;
+}
+
+impl Trait for () {
+ type Assoc = ();
+}
+
+fn unit() -> impl Into<<() as Trait>::Assoc> {}
+
+pub fn ice() {
+ Into::into(unit());
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-67684.rs b/src/test/ui/associated-types/issue-67684.rs
new file mode 100644
index 000000000..49efe8a1b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-67684.rs
@@ -0,0 +1,62 @@
+// check-pass
+
+#![allow(dead_code)]
+
+trait ParseError {
+ type StreamError;
+}
+
+impl<T> ParseError for T {
+ type StreamError = ();
+}
+
+trait Stream {
+ type Item;
+ type Error: ParseError;
+}
+
+trait Parser
+where
+ <Self as Parser>::PartialState: Default,
+{
+ type PartialState;
+ fn parse_mode(_: &Self, _: Self::PartialState) {
+ loop {}
+ }
+}
+
+impl Stream for () {
+ type Item = ();
+ type Error = ();
+}
+
+impl Parser for () {
+ type PartialState = ();
+}
+
+struct AndThen<A, B>(core::marker::PhantomData<(A, B)>);
+
+impl<A, B> Parser for AndThen<A, B>
+where
+ A: Stream,
+ B: Into<<A::Error as ParseError>::StreamError>,
+{
+ type PartialState = ();
+}
+
+fn expr<A>() -> impl Parser
+where
+ A: Stream<Error = <A as Stream>::Item>,
+{
+ AndThen::<A, ()>(core::marker::PhantomData)
+}
+
+fn parse_mode_impl<A>()
+where
+ <A as Stream>::Error: ParseError,
+ A: Stream<Error = <A as Stream>::Item>,
+{
+ Parser::parse_mode(&expr::<A>(), Default::default())
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-69398.rs b/src/test/ui/associated-types/issue-69398.rs
new file mode 100644
index 000000000..ca3d66b1c
--- /dev/null
+++ b/src/test/ui/associated-types/issue-69398.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+pub trait Foo {
+ type Bar;
+}
+
+pub trait Broken {
+ type Assoc;
+ fn broken(&self) where Self::Assoc: Foo;
+}
+
+impl<T> Broken for T {
+ type Assoc = ();
+ fn broken(&self) where Self::Assoc: Foo {
+ let _x: <Self::Assoc as Foo>::Bar;
+ }
+}
+
+fn main() {
+ let _m: &dyn Broken<Assoc=()> = &();
+}
diff --git a/src/test/ui/associated-types/issue-71113.rs b/src/test/ui/associated-types/issue-71113.rs
new file mode 100644
index 000000000..48de89127
--- /dev/null
+++ b/src/test/ui/associated-types/issue-71113.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+use std::borrow::Cow;
+
+enum _Recursive<'a>
+where
+ Self: ToOwned<Owned=Box<Self>>
+{
+ Variant(MyCow<'a, _Recursive<'a>>),
+}
+
+pub struct Wrapper<T>(T);
+
+pub struct MyCow<'a, T: ToOwned<Owned=Box<T>> + 'a>(Wrapper<Cow<'a, T>>);
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-72806.rs b/src/test/ui/associated-types/issue-72806.rs
new file mode 100644
index 000000000..947582503
--- /dev/null
+++ b/src/test/ui/associated-types/issue-72806.rs
@@ -0,0 +1,21 @@
+trait Bar {
+ type Ok;
+ type Sibling: Bar2<Ok=char>;
+}
+trait Bar2 {
+ type Ok;
+}
+
+struct Foo;
+struct Foo2;
+
+impl Bar for Foo {
+ type Ok = ();
+ type Sibling = Foo2;
+ //~^ ERROR type mismatch resolving `<Foo2 as Bar2>::Ok == char`
+}
+impl Bar2 for Foo2 {
+ type Ok = u32;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-72806.stderr b/src/test/ui/associated-types/issue-72806.stderr
new file mode 100644
index 000000000..e95943f34
--- /dev/null
+++ b/src/test/ui/associated-types/issue-72806.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == char`
+ --> $DIR/issue-72806.rs:14:20
+ |
+LL | type Sibling = Foo2;
+ | ^^^^ type mismatch resolving `<Foo2 as Bar2>::Ok == char`
+ |
+note: expected this to be `char`
+ --> $DIR/issue-72806.rs:18:15
+ |
+LL | type Ok = u32;
+ | ^^^
+note: required by a bound in `Bar::Sibling`
+ --> $DIR/issue-72806.rs:3:24
+ |
+LL | type Sibling: Bar2<Ok=char>;
+ | ^^^^^^^ required by this bound in `Bar::Sibling`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/issue-76179.rs b/src/test/ui/associated-types/issue-76179.rs
new file mode 100644
index 000000000..0e086968b
--- /dev/null
+++ b/src/test/ui/associated-types/issue-76179.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(associated_type_defaults)]
+
+use std::io::Read;
+
+trait View {
+ type Deserializers: Deserializer<Item = Self::RequestParams>;
+ type RequestParams = DefaultRequestParams;
+}
+
+struct DefaultRequestParams;
+
+trait Deserializer {
+ type Item;
+ fn deserialize(r: impl Read) -> Self::Item;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-82079.rs b/src/test/ui/associated-types/issue-82079.rs
new file mode 100644
index 000000000..8b3bad707
--- /dev/null
+++ b/src/test/ui/associated-types/issue-82079.rs
@@ -0,0 +1,124 @@
+// revisions: default miropt
+// check-pass
+//[miropt]compile-flags: -Z mir-opt-level=3
+// -^ This flag is for #96395 as a regression test.
+
+mod convenience_operators {
+ use crate::{Op, Relation};
+ use std::ops::AddAssign;
+ use std::ops::Mul;
+
+ impl<C: Op> Relation<C> {
+ pub fn map<F: Fn(C::D) -> D2 + 'static, D2: 'static>(
+ self,
+ f: F,
+ ) -> Relation<impl Op<D = D2, R = C::R>> {
+ self.map_dr(move |x, r| (f(x), r))
+ }
+ }
+
+ impl<K: 'static, V: 'static, C: Op<D = (K, V)>> Relation<C> {
+ pub fn semijoin<C2: Op<D = K, R = R2>, R2, R3: AddAssign<R3>>(
+ self,
+ other: Relation<C2>,
+ ) -> Relation<impl Op<D = C::D, R = R3>>
+ where
+ C::R: Mul<R2, Output = R3>,
+ {
+ self.join(other.map(|x| (x, ()))).map(|(k, x, ())| (k, x))
+ }
+ }
+}
+
+mod core {
+ mod operator {
+ mod join {
+ use super::Op;
+ use crate::core::Relation;
+ use std::ops::{AddAssign, Mul};
+ struct Join<LC, RC> {
+ _left: LC,
+ _right: RC,
+ }
+ impl<
+ LC: Op<D = (K, LD), R = LR>,
+ RC: Op<D = (K, RD), R = RR>,
+ K: 'static,
+ LD: 'static,
+ LR: AddAssign<LR> + Mul<RR, Output = OR>,
+ RD: 'static,
+ RR: AddAssign<RR>,
+ OR: AddAssign<OR>,
+ > Op for Join<LC, RC>
+ {
+ type D = (K, LD, RD);
+ type R = OR;
+ }
+ impl<K: 'static, D: 'static, C: Op<D = (K, D)>> Relation<C> {
+ pub fn join<C2: Op<D = (K, D2)>, D2: 'static, OR: AddAssign<OR>>(
+ self,
+ other: Relation<C2>,
+ ) -> Relation<impl Op<D = (K, D, D2), R = OR>>
+ where
+ C::R: Mul<C2::R, Output = OR>,
+ {
+ Relation {
+ inner: Join {
+ _left: self.inner,
+ _right: other.inner,
+ },
+ }
+ }
+ }
+ }
+ mod map {
+ use super::Op;
+ use crate::core::Relation;
+ use std::ops::AddAssign;
+ struct Map<C, MF> {
+ _inner: C,
+ _op: MF,
+ }
+ impl<
+ D1,
+ R1,
+ D2: 'static,
+ R2: AddAssign<R2>,
+ C: Op<D = D1, R = R1>,
+ MF: Fn(D1, R1) -> (D2, R2),
+ > Op for Map<C, MF>
+ {
+ type D = D2;
+ type R = R2;
+ }
+ impl<C: Op> Relation<C> {
+ pub fn map_dr<F: Fn(C::D, C::R) -> (D2, R2), D2: 'static, R2: AddAssign<R2>>(
+ self,
+ f: F,
+ ) -> Relation<impl Op<D = D2, R = R2>> {
+ Relation {
+ inner: Map {
+ _inner: self.inner,
+ _op: f,
+ },
+ }
+ }
+ }
+ }
+ use std::ops::AddAssign;
+ pub trait Op {
+ type D: 'static;
+ type R: AddAssign<Self::R>;
+ }
+ }
+ pub use self::operator::Op;
+ #[derive(Clone)]
+ pub struct Relation<C> {
+ inner: C,
+ }
+}
+
+use self::core::Op;
+pub use self::core::Relation;
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-85103.rs b/src/test/ui/associated-types/issue-85103.rs
new file mode 100644
index 000000000..c5e138561
--- /dev/null
+++ b/src/test/ui/associated-types/issue-85103.rs
@@ -0,0 +1,9 @@
+#![feature(rustc_attrs)]
+
+use std::borrow::Cow;
+
+#[rustc_layout(debug)]
+type Edges<'a, E> = Cow<'a, [E]>;
+//~^ ERROR layout error: NormalizationFailure
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-85103.stderr b/src/test/ui/associated-types/issue-85103.stderr
new file mode 100644
index 000000000..bddd1dce8
--- /dev/null
+++ b/src/test/ui/associated-types/issue-85103.stderr
@@ -0,0 +1,8 @@
+error: layout error: NormalizationFailure(<[E] as std::borrow::ToOwned>::Owned, Type(<[E] as std::borrow::ToOwned>::Owned))
+ --> $DIR/issue-85103.rs:6:1
+ |
+LL | type Edges<'a, E> = Cow<'a, [E]>;
+ | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/associated-types/issue-87261.rs b/src/test/ui/associated-types/issue-87261.rs
new file mode 100644
index 000000000..384561f8c
--- /dev/null
+++ b/src/test/ui/associated-types/issue-87261.rs
@@ -0,0 +1,99 @@
+trait Foo {}
+
+trait Trait {
+ type Associated;
+}
+trait DerivedTrait: Trait {}
+trait GenericTrait<A> {
+ type Associated;
+}
+
+struct Impl;
+impl Foo for Impl {}
+impl Trait for Impl {
+ type Associated = ();
+}
+impl DerivedTrait for Impl {}
+impl<A> GenericTrait<A> for Impl {
+ type Associated = ();
+}
+
+fn returns_opaque() -> impl Trait + 'static {
+ Impl
+}
+fn returns_opaque_derived() -> impl DerivedTrait + 'static {
+ Impl
+}
+fn returns_opaque_foo() -> impl Trait + Foo {
+ Impl
+}
+fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
+ Impl
+}
+fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
+ Impl
+}
+fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
+ Impl
+}
+fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
+ Impl
+}
+
+fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+
+fn check_generics<A, B, C, D, E, F, G>(a: A, b: B, c: C, d: D, e: E, f: F, g: G)
+where
+ A: Trait + 'static,
+ B: DerivedTrait + 'static,
+ C: Trait + Foo,
+ D: DerivedTrait + Foo,
+ E: GenericTrait<()> + 'static,
+ F: GenericTrait<()> + Foo,
+ G: GenericTrait<()> + GenericTrait<u8>,
+{
+ accepts_trait(a);
+ //~^ ERROR type mismatch resolving `<A as Trait>::Associated == ()`
+
+ accepts_trait(b);
+ //~^ ERROR type mismatch resolving `<B as Trait>::Associated == ()`
+
+ accepts_trait(c);
+ //~^ ERROR type mismatch resolving `<C as Trait>::Associated == ()`
+
+ accepts_trait(d);
+ //~^ ERROR type mismatch resolving `<D as Trait>::Associated == ()`
+
+ accepts_generic_trait(e);
+ //~^ ERROR type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
+
+ accepts_generic_trait(f);
+ //~^ ERROR type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
+
+ accepts_generic_trait(g);
+ //~^ ERROR type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
+}
+
+fn main() {
+ accepts_trait(returns_opaque());
+ //~^ ERROR type mismatch resolving `<impl Trait as Trait>::Associated == ()`
+
+ accepts_trait(returns_opaque_derived());
+ //~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
+
+ accepts_trait(returns_opaque_foo());
+ //~^ ERROR type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
+
+ accepts_trait(returns_opaque_derived_foo());
+ //~^ ERROR type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
+
+ accepts_generic_trait(returns_opaque_generic());
+ //~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
+
+ accepts_generic_trait(returns_opaque_generic_foo());
+ //~^ ERROR type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
+
+ accepts_generic_trait(returns_opaque_generic_duplicate());
+ //~^ ERROR type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
+}
diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr
new file mode 100644
index 000000000..8db4a49da
--- /dev/null
+++ b/src/test/ui/associated-types/issue-87261.stderr
@@ -0,0 +1,266 @@
+error[E0271]: type mismatch resolving `<A as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:56:5
+ |
+LL | accepts_trait(a);
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<A as Trait>::Associated`
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+help: consider constraining the associated type `<A as Trait>::Associated` to `()`
+ |
+LL | A: Trait<Associated = ()> + 'static,
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<B as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:59:5
+ |
+LL | accepts_trait(b);
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<B as Trait>::Associated`
+ = help: consider constraining the associated type `<B as Trait>::Associated` to `()`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+
+error[E0271]: type mismatch resolving `<C as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:62:5
+ |
+LL | accepts_trait(c);
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<C as Trait>::Associated`
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+help: consider constraining the associated type `<C as Trait>::Associated` to `()`
+ |
+LL | C: Trait<Associated = ()> + Foo,
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<D as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:65:5
+ |
+LL | accepts_trait(d);
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<D as Trait>::Associated`
+ = help: consider constraining the associated type `<D as Trait>::Associated` to `()`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+
+error[E0271]: type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`
+ --> $DIR/issue-87261.rs:68:5
+ |
+LL | accepts_generic_trait(e);
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<E as GenericTrait<()>>::Associated`
+note: required by a bound in `accepts_generic_trait`
+ --> $DIR/issue-87261.rs:44:46
+ |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
+help: consider constraining the associated type `<E as GenericTrait<()>>::Associated` to `()`
+ |
+LL | E: GenericTrait<(), Associated = ()> + 'static,
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`
+ --> $DIR/issue-87261.rs:71:5
+ |
+LL | accepts_generic_trait(f);
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<F as GenericTrait<()>>::Associated`
+note: required by a bound in `accepts_generic_trait`
+ --> $DIR/issue-87261.rs:44:46
+ |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
+help: consider constraining the associated type `<F as GenericTrait<()>>::Associated` to `()`
+ |
+LL | F: GenericTrait<(), Associated = ()> + Foo,
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
+ --> $DIR/issue-87261.rs:74:5
+ |
+LL | accepts_generic_trait(g);
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<G as GenericTrait<()>>::Associated`
+ = help: consider constraining the associated type `<G as GenericTrait<()>>::Associated` to `()`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `accepts_generic_trait`
+ --> $DIR/issue-87261.rs:44:46
+ |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
+
+error[E0271]: type mismatch resolving `<impl Trait as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:79:5
+ |
+LL | fn returns_opaque() -> impl Trait + 'static {
+ | -------------------- the found opaque type
+...
+LL | accepts_trait(returns_opaque());
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl Trait as Trait>::Associated`
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+help: consider constraining the associated type `<impl Trait as Trait>::Associated` to `()`
+ |
+LL | fn returns_opaque() -> impl Trait<Associated = ()> + 'static {
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:82:5
+ |
+LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static {
+ | --------------------------- the found opaque type
+...
+LL | accepts_trait(returns_opaque_derived());
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl DerivedTrait as Trait>::Associated`
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+help: consider constraining the associated type `<impl DerivedTrait as Trait>::Associated` to `()`
+ |
+LL | fn returns_opaque_derived() -> impl DerivedTrait<Associated = ()> + 'static {
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<impl Trait + Foo as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:85:5
+ |
+LL | fn returns_opaque_foo() -> impl Trait + Foo {
+ | ---------------- the found opaque type
+...
+LL | accepts_trait(returns_opaque_foo());
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl Trait + Foo as Trait>::Associated`
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+help: consider constraining the associated type `<impl Trait + Foo as Trait>::Associated` to `()`
+ |
+LL | fn returns_opaque_foo() -> impl Trait<Associated = ()> + Foo {
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<impl DerivedTrait + Foo as Trait>::Associated == ()`
+ --> $DIR/issue-87261.rs:88:5
+ |
+LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
+ | ----------------------- the found opaque type
+...
+LL | accepts_trait(returns_opaque_derived_foo());
+ | ^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl DerivedTrait + Foo as Trait>::Associated`
+ = help: consider constraining the associated type `<impl DerivedTrait + Foo as Trait>::Associated` to `()`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `accepts_trait`
+ --> $DIR/issue-87261.rs:43:27
+ |
+LL | fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait`
+
+error[E0271]: type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`
+ --> $DIR/issue-87261.rs:91:5
+ |
+LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
+ | ------------------------------- the found opaque type
+...
+LL | accepts_generic_trait(returns_opaque_generic());
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated`
+note: required by a bound in `accepts_generic_trait`
+ --> $DIR/issue-87261.rs:44:46
+ |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
+help: consider constraining the associated type `<impl GenericTrait<()> as GenericTrait<()>>::Associated` to `()`
+ |
+LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static {
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated == ()`
+ --> $DIR/issue-87261.rs:94:5
+ |
+LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
+ | --------------------------- the found opaque type
+...
+LL | accepts_generic_trait(returns_opaque_generic_foo());
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated`
+note: required by a bound in `accepts_generic_trait`
+ --> $DIR/issue-87261.rs:44:46
+ |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
+help: consider constraining the associated type `<impl GenericTrait<()> + Foo as GenericTrait<()>>::Associated` to `()`
+ |
+LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo {
+ | +++++++++++++++++
+
+error[E0271]: type mismatch resolving `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
+ --> $DIR/issue-87261.rs:97:5
+ |
+LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
+ | ---------------------------------------- the found opaque type
+...
+LL | accepts_generic_trait(returns_opaque_generic_duplicate());
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ |
+ = note: expected unit type `()`
+ found associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated`
+ = help: consider constraining the associated type `<impl GenericTrait<()> + GenericTrait<u8> as GenericTrait<()>>::Associated` to `()`
+ = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+note: required by a bound in `accepts_generic_trait`
+ --> $DIR/issue-87261.rs:44:46
+ |
+LL | fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}
+ | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/issue-88856.rs b/src/test/ui/associated-types/issue-88856.rs
new file mode 100644
index 000000000..7cae7c71c
--- /dev/null
+++ b/src/test/ui/associated-types/issue-88856.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+#![feature(generic_const_exprs)]
+#![allow(incomplete_features)]
+
+pub trait Trait{
+ type R;
+ fn func(self)->Self::R;
+}
+
+pub struct TraitImpl<const N:usize>(pub i32);
+
+impl<const N:usize> Trait for TraitImpl<N>
+where [();N/2]:,
+{
+ type R = Self;
+ fn func(self)->Self::R {
+ self
+ }
+}
+
+fn sample<P,Convert>(p:P,f:Convert) -> i32
+where
+ P:Trait,Convert:Fn(P::R)->i32
+{
+ f(p.func())
+}
+
+fn main() {
+ let t = TraitImpl::<10>(4);
+ sample(t,|x|x.0);
+}
diff --git a/src/test/ui/associated-types/issue-91069.rs b/src/test/ui/associated-types/issue-91069.rs
new file mode 100644
index 000000000..109c2eed2
--- /dev/null
+++ b/src/test/ui/associated-types/issue-91069.rs
@@ -0,0 +1,24 @@
+// check-pass
+
+pub trait Associate {
+ type Associated;
+}
+
+pub struct Wrap<'a> {
+ pub field: &'a i32,
+}
+
+pub trait Create<T> {
+ fn create() -> Self;
+}
+
+pub fn oh_no<'a, T>()
+where
+ Wrap<'a>: Associate,
+ <Wrap<'a> as Associate>::Associated: Create<T>,
+{
+ <Wrap<'a> as Associate>::Associated::create();
+}
+
+
+pub fn main() {}
diff --git a/src/test/ui/associated-types/issue-91231.rs b/src/test/ui/associated-types/issue-91231.rs
new file mode 100644
index 000000000..3c1cb81f0
--- /dev/null
+++ b/src/test/ui/associated-types/issue-91231.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(extern_types)]
+#![allow(dead_code)]
+
+extern {
+ type Extern;
+}
+
+trait Trait {
+ type Type;
+}
+
+#[inline]
+fn f<'a>(_: <&'a Extern as Trait>::Type) where &'a Extern: Trait {}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/issue-91234.rs b/src/test/ui/associated-types/issue-91234.rs
new file mode 100644
index 000000000..2f6c2d3ae
--- /dev/null
+++ b/src/test/ui/associated-types/issue-91234.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+struct Struct;
+
+trait Trait {
+ type Type;
+}
+
+enum Enum<'a> where &'a Struct: Trait {
+ Variant(<&'a Struct as Trait>::Type)
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/missing-associated-types.rs b/src/test/ui/associated-types/missing-associated-types.rs
new file mode 100644
index 000000000..3c8410e39
--- /dev/null
+++ b/src/test/ui/associated-types/missing-associated-types.rs
@@ -0,0 +1,27 @@
+use std::ops::{Add, Sub, Mul, Div};
+trait X<Rhs>: Mul<Rhs> + Div<Rhs> {}
+trait Y<Rhs>: Div<Rhs, Output = Rhs> {
+ type A;
+}
+trait Z<Rhs>: Div<Rhs> {
+ type A;
+ type B;
+}
+trait Fine<Rhs>: Div<Rhs, Output = Rhs> {}
+
+type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
+//~^ ERROR only auto traits can be used as additional traits in a trait object
+//~| ERROR the value of the associated types
+type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
+//~^ ERROR only auto traits can be used as additional traits in a trait object
+//~| ERROR the value of the associated types
+type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
+//~^ ERROR only auto traits can be used as additional traits in a trait object
+//~| ERROR the value of the associated types
+type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
+//~^ ERROR only auto traits can be used as additional traits in a trait object
+//~| ERROR the value of the associated types
+type Bal<Rhs> = dyn X<Rhs>;
+//~^ ERROR the value of the associated types
+
+fn main() {}
diff --git a/src/test/ui/associated-types/missing-associated-types.stderr b/src/test/ui/associated-types/missing-associated-types.stderr
new file mode 100644
index 000000000..f617df984
--- /dev/null
+++ b/src/test/ui/associated-types/missing-associated-types.stderr
@@ -0,0 +1,129 @@
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/missing-associated-types.rs:12:32
+ |
+LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
+ | -------- ^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error[E0191]: the value of the associated types `A` (from trait `Y`), `Output` (from trait `Add`), `Output` (from trait `Mul`), `Output` (from trait `Sub`) must be specified
+ --> $DIR/missing-associated-types.rs:12:21
+ |
+LL | type A;
+ | ------ `A` defined here
+...
+LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
+ | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated type `A` must be specified
+ | | | |
+ | | | associated type `Output` must be specified
+ | | associated type `Output` must be specified
+ | associated type `Output` must be specified
+ |
+help: specify the associated types
+ |
+LL | type Foo<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs, Output = Type> + Y<Rhs, A = Type>;
+ | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/missing-associated-types.rs:15:32
+ |
+LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
+ | -------- ^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error[E0191]: the value of the associated types `A` (from trait `Z`), `B` (from trait `Z`), `Output` (from trait `Add`), `Output` (from trait `Div`), `Output` (from trait `Div`), `Output` (from trait `Mul`), `Output` (from trait `Sub`) must be specified
+ --> $DIR/missing-associated-types.rs:15:21
+ |
+LL | type A;
+ | ------ `A` defined here
+LL | type B;
+ | ------ `B` defined here
+...
+LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
+ | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated types `A`, `B`, `Output` must be specified
+ | | | |
+ | | | associated types `Output` (from trait `Mul`), `Output` (from trait `Div`) must be specified
+ | | associated type `Output` must be specified
+ | associated type `Output` must be specified
+ |
+help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
+ --> $DIR/missing-associated-types.rs:15:43
+ |
+LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
+ | ^^^^^^
+help: specify the associated types
+ |
+LL | type Bar<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs> + Z<Rhs, A = Type, B = Type, Output = Type>;
+ | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/missing-associated-types.rs:18:32
+ |
+LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
+ | -------- ^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Y<Rhs> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error[E0191]: the value of the associated types `A` (from trait `Y`), `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
+ --> $DIR/missing-associated-types.rs:18:21
+ |
+LL | type A;
+ | ------ `A` defined here
+...
+LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
+ | ^^^^^^^^ ^^^^^^^^ ^^^^^^ associated type `A` must be specified
+ | | |
+ | | associated type `Output` must be specified
+ | associated type `Output` must be specified
+ |
+help: specify the associated types
+ |
+LL | type Baz<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Y<Rhs, A = Type>;
+ | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
+
+error[E0225]: only auto traits can be used as additional traits in a trait object
+ --> $DIR/missing-associated-types.rs:21:32
+ |
+LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
+ | -------- ^^^^^^^^ additional non-auto trait
+ | |
+ | first non-auto trait
+ |
+ = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Fine<Rhs> {}`
+ = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
+
+error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
+ --> $DIR/missing-associated-types.rs:21:21
+ |
+LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
+ | ^^^^^^^^ ^^^^^^^^ associated type `Output` must be specified
+ | |
+ | associated type `Output` must be specified
+ |
+help: specify the associated types
+ |
+LL | type Bat<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Fine<Rhs>;
+ | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0191]: the value of the associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified
+ --> $DIR/missing-associated-types.rs:24:21
+ |
+LL | type Bal<Rhs> = dyn X<Rhs>;
+ | ^^^^^^ associated types `Output` (from trait `Mul`), `Output` (from trait `Div`) must be specified
+ |
+ = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0191, E0225.
+For more information about an error, try `rustc --explain E0191`.
diff --git a/src/test/ui/associated-types/normalization-debruijn-1.rs b/src/test/ui/associated-types/normalization-debruijn-1.rs
new file mode 100644
index 000000000..a5abf1ba9
--- /dev/null
+++ b/src/test/ui/associated-types/normalization-debruijn-1.rs
@@ -0,0 +1,36 @@
+// build-pass
+// edition:2018
+
+// Regression test to ensure we handle debruijn indices correctly in projection
+// normalization under binders. Found in crater run for #85499
+
+use std::future::Future;
+use std::pin::Pin;
+pub enum Outcome<S, E> {
+ Success((S, E)),
+}
+pub struct Request<'r> {
+ _marker: std::marker::PhantomData<&'r ()>,
+}
+pub trait FromRequest<'r>: Sized {
+ type Error;
+ fn from_request<'life0>(
+ request: &'r Request<'life0>,
+ ) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>>>>;
+}
+impl<'r, T: FromRequest<'r>> FromRequest<'r> for Option<T> {
+ type Error = ();
+ fn from_request<'life0>(
+ request: &'r Request<'life0>,
+ ) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>>>> {
+ Box::pin(async move {
+ let request = request;
+ match T::from_request(request).await {
+ _ => todo!(),
+ }
+ });
+ todo!()
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/normalization-debruijn-2.rs b/src/test/ui/associated-types/normalization-debruijn-2.rs
new file mode 100644
index 000000000..abe248e16
--- /dev/null
+++ b/src/test/ui/associated-types/normalization-debruijn-2.rs
@@ -0,0 +1,31 @@
+// build-pass
+// edition:2018
+
+// Regression test to ensure we handle debruijn indices correctly in projection
+// normalization under binders. Found in crater run for #85499
+
+use std::future::Future;
+use std::pin::Pin;
+pub enum Outcome<S, E> {
+ Success(S),
+ Failure(E),
+}
+pub struct Request<'r> {
+ _marker: std::marker::PhantomData<&'r ()>,
+}
+pub trait FromRequest<'r>: Sized {
+ type Error;
+ fn from_request<'life0>(
+ request: &'r Request<'life0>,
+ ) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>>>>;
+}
+pub struct S<T> {
+ _marker: std::marker::PhantomData<T>,
+}
+impl<'r, T: FromRequest<'r>> S<T> {
+ pub async fn from_request(request: &'r Request<'_>) {
+ let _ = T::from_request(request).await;
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/normalization-debruijn-3.rs b/src/test/ui/associated-types/normalization-debruijn-3.rs
new file mode 100644
index 000000000..2bea78cf7
--- /dev/null
+++ b/src/test/ui/associated-types/normalization-debruijn-3.rs
@@ -0,0 +1,41 @@
+// build-pass
+// edition:2018
+
+// Regression test to ensure we handle debruijn indices correctly in projection
+// normalization under binders. Found in crater run for #85499
+
+use std::future::{Future, Ready};
+async fn read() {
+ let _ = connect(&()).await;
+}
+async fn connect<A: ToSocketAddr>(addr: A) {
+ let _ = addr.to_socket_addr().await;
+}
+pub trait ToSocketAddr {
+ type Future: Future<Output = ()>;
+ fn to_socket_addr(&self) -> Self::Future;
+}
+impl ToSocketAddr for &() {
+ type Future = Ready<()>;
+ fn to_socket_addr(&self) -> Self::Future {
+ unimplemented!()
+ }
+}
+struct Server;
+impl Server {
+ fn and_then<F>(self, _fun: F) -> AndThen<F> {
+ unimplemented!()
+ }
+}
+struct AndThen<F> {
+ _marker: std::marker::PhantomData<F>,
+}
+pub async fn run<F>(_: F) {
+}
+fn main() {
+ let _ = async {
+ let server = Server;
+ let verification_route = server.and_then(read);
+ run(verification_route).await;
+ };
+}
diff --git a/src/test/ui/associated-types/normalization-generality-2.rs b/src/test/ui/associated-types/normalization-generality-2.rs
new file mode 100644
index 000000000..d8790bb2d
--- /dev/null
+++ b/src/test/ui/associated-types/normalization-generality-2.rs
@@ -0,0 +1,30 @@
+// build-pass
+
+// Ensures that we don't regress on "implementation is not general enough" when
+// normalizating under binders. Unlike `normalization-generality.rs`, this also produces
+// type outlives predicates that we must ignore.
+
+pub unsafe trait Yokeable<'a> {
+ type Output: 'a;
+}
+pub struct Yoke<Y: for<'a> Yokeable<'a>> {
+ _marker: std::marker::PhantomData<Y>,
+}
+impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
+ pub fn project<P>(
+ &self,
+ _f: for<'a> fn(&<Y as Yokeable<'a>>::Output, &'a ()) -> <P as Yokeable<'a>>::Output,
+ ) -> Yoke<P>
+ where
+ P: for<'a> Yokeable<'a>,
+ {
+ unimplemented!()
+ }
+}
+pub fn slice(y: Yoke<&'static str>) -> Yoke<&'static [u8]> {
+ y.project(move |yk, _| yk.as_bytes())
+}
+unsafe impl<'a, T: 'static + ?Sized> Yokeable<'a> for &'static T {
+ type Output = &'a T;
+}
+fn main() {}
diff --git a/src/test/ui/associated-types/normalization-generality.rs b/src/test/ui/associated-types/normalization-generality.rs
new file mode 100644
index 000000000..f8e3f5b58
--- /dev/null
+++ b/src/test/ui/associated-types/normalization-generality.rs
@@ -0,0 +1,36 @@
+// build-pass
+
+// Ensures that we don't regress on "implementation is not general enough" when
+// normalizating under binders.
+
+#![feature(no_core)]
+
+pub trait Yokeable<'a> {
+ type Output: 'a;
+}
+
+pub struct Yoke<Y: for<'a> Yokeable<'a>> {
+ _yokeable: Y,
+}
+
+impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
+ pub fn project<'this, P>(
+ &'this self,
+ _f: for<'a> fn(<Y as Yokeable<'a>>::Output, &'a ()) -> <P as Yokeable<'a>>::Output,
+ ) -> Yoke<P>
+ where
+ P: for<'a> Yokeable<'a>,
+ {
+ unimplemented!()
+ }
+}
+
+pub fn slice(y: Yoke<&'static ()>) -> Yoke<&'static ()> {
+ y.project(move |yk, _| yk)
+}
+
+impl<'a, T> Yokeable<'a> for &'static T {
+ type Output = &'a T;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/normalization-probe-cycle.rs b/src/test/ui/associated-types/normalization-probe-cycle.rs
new file mode 100644
index 000000000..9c1a488e9
--- /dev/null
+++ b/src/test/ui/associated-types/normalization-probe-cycle.rs
@@ -0,0 +1,25 @@
+// Regression test for #77656
+
+// check-pass
+
+trait Value: PartialOrd {}
+
+impl<T: PartialOrd> Value for T {}
+
+trait Distance
+where
+ Self: PartialOrd<<Self as Distance>::Value>,
+ Self: PartialOrd,
+{
+ type Value: Value;
+}
+
+impl<T: Value> Distance for T {
+ type Value = T;
+}
+
+trait Proximity<T = Self> {
+ type Distance: Distance;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/normalize-cycle-in-eval-no-region.rs b/src/test/ui/associated-types/normalize-cycle-in-eval-no-region.rs
new file mode 100644
index 000000000..0fd2c7079
--- /dev/null
+++ b/src/test/ui/associated-types/normalize-cycle-in-eval-no-region.rs
@@ -0,0 +1,20 @@
+// Case that the fix for #74868 also allowed to compile
+
+// check-pass
+
+trait BoxedDsl {
+ type Output;
+}
+
+impl<T> BoxedDsl for T
+where
+ T: BoxedDsl,
+{
+ type Output = <T as BoxedDsl>::Output;
+}
+
+trait HandleUpdate {}
+
+impl<T> HandleUpdate for T where T: BoxedDsl<Output = ()> {}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/normalize-cycle-in-eval.rs b/src/test/ui/associated-types/normalize-cycle-in-eval.rs
new file mode 100644
index 000000000..dff4c9051
--- /dev/null
+++ b/src/test/ui/associated-types/normalize-cycle-in-eval.rs
@@ -0,0 +1,43 @@
+// regression test for #74868
+
+// check-pass
+
+trait BoxedDsl<'a> {
+ type Output;
+}
+
+impl<'a, T> BoxedDsl<'a> for T
+where
+ T: BoxedDsl<'a>,
+{
+ type Output = <T as BoxedDsl<'a>>::Output;
+}
+
+// Showing this trait is wf requires proving
+// Self: HandleUpdate
+//
+// The impl below is a candidate for this projection, as well as the `Self:
+// HandleUpdate` bound in the environment.
+// We evaluate both candidates to see if we need to consider both applicable.
+// Evaluating the impl candidate requires evaluating
+// <T as BoxedDsl<'static>>::Output == ()
+// The above impl cause normalizing the above type normalize to itself.
+//
+// This previously compiled because we would generate a new region
+// variable each time around the cycle, and evaluation would eventually return
+// `EvaluatedToErr` from the `Self: Sized` in the impl, which would in turn
+// leave the bound as the only candidate.
+//
+// #73452 changed this so that region variables are canonicalized when we
+// normalize, which means that the projection cycle is detected before
+// evaluation returns EvaluatedToErr. The cycle resulted in an error being
+// emitted immediately, causing this to fail to compile.
+//
+// To fix this, normalization doesn't directly emit errors when it finds a
+// cycle, instead letting the caller handle it. This restores the original
+// behavior.
+trait HandleUpdate {}
+
+impl<T> HandleUpdate for T where T: BoxedDsl<'static, Output = ()> {}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/object-method-numbering.rs b/src/test/ui/associated-types/object-method-numbering.rs
new file mode 100644
index 000000000..bf80a80f4
--- /dev/null
+++ b/src/test/ui/associated-types/object-method-numbering.rs
@@ -0,0 +1,28 @@
+// run-pass
+// Test for using an object with an associated type binding as the
+// instantiation for a generic type with a bound.
+
+
+trait SomeTrait {
+ type SomeType;
+
+ fn get(&self) -> Self::SomeType;
+}
+
+fn get_int<T:SomeTrait<SomeType=i32>+?Sized>(x: &T) -> i32 {
+ x.get()
+}
+
+impl SomeTrait for i32 {
+ type SomeType = i32;
+ fn get(&self) -> i32 {
+ *self
+ }
+}
+
+fn main() {
+ let x = 22;
+ let x1: &dyn SomeTrait<SomeType=i32> = &x;
+ let y = get_int(x1);
+ assert_eq!(x, y);
+}
diff --git a/src/test/ui/associated-types/object-normalization.rs b/src/test/ui/associated-types/object-normalization.rs
new file mode 100644
index 000000000..1f93248e1
--- /dev/null
+++ b/src/test/ui/associated-types/object-normalization.rs
@@ -0,0 +1,26 @@
+// ignore-tidy-linelength
+
+// Check that we normalize super predicates for object candidates.
+
+// check-pass
+
+use std::ops::Index;
+
+fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
+ // To prove
+ // `dyn SVec<Item = T, Output = T>: SVec`
+ // we need to show
+ // `dyn SVec<Item = T, Output = T> as Index>::Output == <dyn SVec<Item = T, Output = T> as SVec>::Item`
+ // which, with the current normalization strategy, has to be eagerly
+ // normalized to:
+ // `dyn SVec<Item = T, Output = T> as Index>::Output == T`.
+ let _ = s.len();
+}
+
+trait SVec: Index<usize, Output = <Self as SVec>::Item> {
+ type Item;
+
+ fn len(&self) -> usize;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/param-env-normalize-cycle.rs b/src/test/ui/associated-types/param-env-normalize-cycle.rs
new file mode 100644
index 000000000..12db595ed
--- /dev/null
+++ b/src/test/ui/associated-types/param-env-normalize-cycle.rs
@@ -0,0 +1,39 @@
+// Minimized case from typenum that didn't compile because:
+// - We tried to normalize the ParamEnv of the second impl
+// - This requires trying to normalize `GrEq<Self, Square<Square<U>>>`
+// - This requires proving `Square<Square<U>>: Sized` so that the first impl
+// applies
+// - This requires Providing `Square<Square<U>>` is well-formed, so that we
+// can use the `Sized` bound on `Mul::Output`
+// - This requires proving `Square<U>: Mul`
+// - But first we tried normalizing the whole obligation, including the
+// ParamEnv, which leads to a cycle error.
+
+// check-pass
+
+trait PrivateSquareRoot {}
+
+pub trait Mul<Rhs = Self> {
+ type Output;
+}
+
+pub trait IsGreaterOrEqual<Rhs> {
+ type Output;
+}
+
+pub type Square<A> = <A as Mul>::Output;
+pub type GrEq<A, B> = <A as IsGreaterOrEqual<B>>::Output;
+
+impl<A, B> IsGreaterOrEqual<B> for A {
+ type Output = ();
+}
+
+impl<U> PrivateSquareRoot for U
+where
+ U: Mul,
+ Square<U>: Mul,
+ GrEq<Self, Square<Square<U>>>: Sized,
+{
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs
new file mode 100644
index 000000000..4b3d6e9d6
--- /dev/null
+++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs
@@ -0,0 +1,33 @@
+trait Bar {}
+
+trait Foo {
+ type Assoc: Bar;
+}
+
+impl Foo for () {
+ type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
+}
+
+trait Baz
+where
+ Self::Assoc: Bar,
+{
+ type Assoc;
+}
+
+impl Baz for () {
+ type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
+}
+
+trait Bat
+where
+ <Self as Bat>::Assoc: Bar,
+{
+ type Assoc;
+}
+
+impl Bat for () {
+ type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
new file mode 100644
index 000000000..2e7a1dd2a
--- /dev/null
+++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
@@ -0,0 +1,45 @@
+error[E0277]: the trait bound `bool: Bar` is not satisfied
+ --> $DIR/point-at-type-on-obligation-failure-2.rs:8:18
+ |
+LL | type Assoc = bool;
+ | ^^^^ the trait `Bar` is not implemented for `bool`
+ |
+note: required by a bound in `Foo::Assoc`
+ --> $DIR/point-at-type-on-obligation-failure-2.rs:4:17
+ |
+LL | type Assoc: Bar;
+ | ^^^ required by this bound in `Foo::Assoc`
+
+error[E0277]: the trait bound `bool: Bar` is not satisfied
+ --> $DIR/point-at-type-on-obligation-failure-2.rs:19:18
+ |
+LL | type Assoc = bool;
+ | ^^^^ the trait `Bar` is not implemented for `bool`
+ |
+note: required by a bound in `Baz::Assoc`
+ --> $DIR/point-at-type-on-obligation-failure-2.rs:13:18
+ |
+LL | Self::Assoc: Bar,
+ | ^^^ required by this bound in `Baz::Assoc`
+LL | {
+LL | type Assoc;
+ | ----- required by a bound in this
+
+error[E0277]: the trait bound `bool: Bar` is not satisfied
+ --> $DIR/point-at-type-on-obligation-failure-2.rs:30:18
+ |
+LL | type Assoc = bool;
+ | ^^^^ the trait `Bar` is not implemented for `bool`
+ |
+note: required by a bound in `Bat::Assoc`
+ --> $DIR/point-at-type-on-obligation-failure-2.rs:24:27
+ |
+LL | <Self as Bat>::Assoc: Bar,
+ | ^^^ required by this bound in `Bat::Assoc`
+LL | {
+LL | type Assoc;
+ | ----- required by a bound in this
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure.rs b/src/test/ui/associated-types/point-at-type-on-obligation-failure.rs
new file mode 100644
index 000000000..666660068
--- /dev/null
+++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure.rs
@@ -0,0 +1,21 @@
+trait Bar {
+ type Ok;
+ type Sibling: Bar2<Ok=Self::Ok>;
+}
+trait Bar2 {
+ type Ok;
+}
+
+struct Foo;
+struct Foo2;
+
+impl Bar for Foo {
+ type Ok = ();
+ type Sibling = Foo2;
+ //~^ ERROR type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
+}
+impl Bar2 for Foo2 {
+ type Ok = u32;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr b/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr
new file mode 100644
index 000000000..9afbe82c3
--- /dev/null
+++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr
@@ -0,0 +1,20 @@
+error[E0271]: type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
+ --> $DIR/point-at-type-on-obligation-failure.rs:14:20
+ |
+LL | type Sibling = Foo2;
+ | ^^^^ type mismatch resolving `<Foo2 as Bar2>::Ok == ()`
+ |
+note: expected this to be `()`
+ --> $DIR/point-at-type-on-obligation-failure.rs:18:15
+ |
+LL | type Ok = u32;
+ | ^^^
+note: required by a bound in `Bar::Sibling`
+ --> $DIR/point-at-type-on-obligation-failure.rs:3:24
+ |
+LL | type Sibling: Bar2<Ok=Self::Ok>;
+ | ^^^^^^^^^^^ required by this bound in `Bar::Sibling`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/project-defer-unification.rs b/src/test/ui/associated-types/project-defer-unification.rs
new file mode 100644
index 000000000..547ff45c2
--- /dev/null
+++ b/src/test/ui/associated-types/project-defer-unification.rs
@@ -0,0 +1,104 @@
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unreachable_code)]
+// A regression test extracted from image-0.3.11. The point of
+// failure was in `index_colors` below.
+
+use std::ops::{Deref, DerefMut};
+
+#[derive(Copy, Clone)]
+pub struct Luma<T: Primitive> { pub data: [T; 1] }
+
+impl<T: Primitive + 'static> Pixel for Luma<T> {
+ type Subpixel = T;
+}
+
+pub struct ImageBuffer<P: Pixel, Container> {
+ pixels: P,
+ c: Container,
+}
+
+pub trait GenericImage: Sized {
+ type Pixel: Pixel;
+}
+
+pub trait Pixel: Copy + Clone {
+ type Subpixel: Primitive;
+}
+
+pub trait Primitive: Copy + PartialOrd<Self> + Clone {
+}
+
+impl<P, Container> GenericImage for ImageBuffer<P, Container>
+where P: Pixel + 'static,
+ Container: Deref<Target=[P::Subpixel]> + DerefMut,
+ P::Subpixel: 'static {
+
+ type Pixel = P;
+}
+
+impl Primitive for u8 { }
+
+impl<P, Container> ImageBuffer<P, Container>
+where P: Pixel + 'static,
+ P::Subpixel: 'static,
+ Container: Deref<Target=[P::Subpixel]>
+{
+ pub fn pixels<'a>(&'a self) -> Pixels<'a, Self> {
+ loop { }
+ }
+
+ pub fn pixels_mut(&mut self) -> PixelsMut<P> {
+ loop { }
+ }
+}
+
+pub struct Pixels<'a, I: 'a> {
+ image: &'a I,
+ x: u32,
+ y: u32,
+ width: u32,
+ height: u32
+}
+
+impl<'a, I: GenericImage> Iterator for Pixels<'a, I> {
+ type Item = (u32, u32, I::Pixel);
+
+ fn next(&mut self) -> Option<(u32, u32, I::Pixel)> {
+ loop { }
+ }
+}
+
+pub struct PixelsMut<'a, P: Pixel + 'a> where P::Subpixel: 'a {
+ chunks: &'a mut P::Subpixel
+}
+
+impl<'a, P: Pixel + 'a> Iterator for PixelsMut<'a, P> where P::Subpixel: 'a {
+ type Item = &'a mut P;
+
+ fn next(&mut self) -> Option<&'a mut P> {
+ loop { }
+ }
+}
+
+pub fn index_colors<Pix>(image: &ImageBuffer<Pix, Vec<u8>>)
+ -> ImageBuffer<Luma<u8>, Vec<u8>>
+where Pix: Pixel<Subpixel=u8> + 'static,
+{
+ // When NLL-enabled, `let mut` below is deemed unnecessary (due to
+ // the remaining code being unreachable); so ignore that lint.
+ #![allow(unused_mut)]
+
+ let mut indices: ImageBuffer<_,Vec<_>> = loop { };
+ for (pixel, idx) in image.pixels().zip(indices.pixels_mut()) {
+ // failured occurred here ^^ because we were requiring that we
+ // could project Pixel or Subpixel from `T_indices` (type of
+ // `indices`), but the type is insufficiently constrained
+ // until we reach the return below.
+ }
+ indices
+}
+
+fn main() { }
diff --git a/src/test/ui/associated-types/project-recursion-limit-non-fatal.rs b/src/test/ui/associated-types/project-recursion-limit-non-fatal.rs
new file mode 100644
index 000000000..3e68b1401
--- /dev/null
+++ b/src/test/ui/associated-types/project-recursion-limit-non-fatal.rs
@@ -0,0 +1,58 @@
+// Regression test for #80953. Hitting the recursion limit in projection
+// is non-fatal. The above code, minimised from wundergraph shows a case
+// where this is relied on.
+
+// check-pass
+
+struct AlternateTable {}
+struct AlternateQuery {}
+
+pub trait Query {}
+pub trait AsQuery {
+ type Query;
+}
+impl<T: Query> AsQuery for T {
+ type Query = Self;
+}
+impl AsQuery for AlternateTable {
+ type Query = AlternateQuery;
+}
+
+pub trait Table: AsQuery {
+ type PrimaryKey;
+}
+impl Table for AlternateTable {
+ type PrimaryKey = ();
+}
+
+pub trait FilterDsl<Predicate> {
+ type Output;
+}
+pub type Filter<Source, Predicate> = <Source as FilterDsl<Predicate>>::Output;
+impl<T, Predicate> FilterDsl<Predicate> for T
+where
+ T: Table,
+ T::Query: FilterDsl<Predicate>,
+{
+ type Output = Filter<T::Query, Predicate>;
+}
+impl<Predicate> FilterDsl<Predicate> for AlternateQuery {
+ type Output = &'static str;
+}
+
+pub trait HandleDelete {
+ type Filter;
+}
+impl<T> HandleDelete for T
+where
+ T: Table,
+ T::Query: FilterDsl<T::PrimaryKey>,
+ Filter<T::Query, T::PrimaryKey>: ,
+{
+ type Filter = Filter<T::Query, T::PrimaryKey>;
+}
+
+fn main() {
+ let x: <AlternateTable as HandleDelete>::Filter = "Hello, world";
+ println!("{}", x);
+}
diff --git a/src/test/ui/associated-types/substs-ppaux.normal.stderr b/src/test/ui/associated-types/substs-ppaux.normal.stderr
new file mode 100644
index 000000000..085c56870
--- /dev/null
+++ b/src/test/ui/associated-types/substs-ppaux.normal.stderr
@@ -0,0 +1,89 @@
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:16:17
+ |
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>} defined here
+...
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
+help: use parentheses to call this function
+ |
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:25:17
+ |
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>} defined here
+...
+LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
+help: use parentheses to call this function
+ |
+LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:33:17
+ |
+LL | fn baz() {}
+ | -------- fn() {<i8 as Foo<'static, 'static, u8>>::baz} defined here
+...
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
+help: use parentheses to call this function
+ |
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:41:17
+ |
+LL | fn foo<'z>() where &'z (): Sized {
+ | -------------------------------- fn() {foo::<'static>} defined here
+...
+LL | let x: () = foo::<'static>;
+ | -- ^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {foo::<'static>}`
+help: use parentheses to call this function
+ |
+LL | let x: () = foo::<'static>();
+ | ++
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+ --> $DIR/substs-ppaux.rs:49:5
+ |
+LL | <str as Foo<u8>>::bar;
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `str`
+note: required because of the requirements on the impl of `Foo<'_, '_, u8>` for `str`
+ --> $DIR/substs-ppaux.rs:11:17
+ |
+LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
+ | ^^^^^^^^^^^^^^ ^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/substs-ppaux.rs b/src/test/ui/associated-types/substs-ppaux.rs
new file mode 100644
index 000000000..66cd94d7a
--- /dev/null
+++ b/src/test/ui/associated-types/substs-ppaux.rs
@@ -0,0 +1,52 @@
+//
+// revisions: verbose normal
+//
+//[verbose] compile-flags: -Z verbose
+
+trait Foo<'b, 'c, S=u32> {
+ fn bar<'a, T>() where T: 'a {}
+ fn baz() {}
+}
+
+impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
+
+fn main() {}
+
+fn foo<'z>() where &'z (): Sized {
+ let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
+ //[verbose]~^ ERROR mismatched types
+ //[verbose]~| expected unit type `()`
+ //[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
+ //[normal]~^^^^ ERROR mismatched types
+ //[normal]~| expected unit type `()`
+ //[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
+
+
+ let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
+ //[verbose]~^ ERROR mismatched types
+ //[verbose]~| expected unit type `()`
+ //[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
+ //[normal]~^^^^ ERROR mismatched types
+ //[normal]~| expected unit type `()`
+ //[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
+
+ let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
+ //[verbose]~^ ERROR mismatched types
+ //[verbose]~| expected unit type `()`
+ //[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
+ //[normal]~^^^^ ERROR mismatched types
+ //[normal]~| expected unit type `()`
+ //[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
+
+ let x: () = foo::<'static>;
+ //[verbose]~^ ERROR mismatched types
+ //[verbose]~| expected unit type `()`
+ //[verbose]~| found fn item `fn() {foo::<ReStatic>}`
+ //[normal]~^^^^ ERROR mismatched types
+ //[normal]~| expected unit type `()`
+ //[normal]~| found fn item `fn() {foo::<'static>}`
+
+ <str as Foo<u8>>::bar;
+ //[verbose]~^ ERROR the size for values of type
+ //[normal]~^^ ERROR the size for values of type
+}
diff --git a/src/test/ui/associated-types/substs-ppaux.verbose.stderr b/src/test/ui/associated-types/substs-ppaux.verbose.stderr
new file mode 100644
index 000000000..b831f3b7a
--- /dev/null
+++ b/src/test/ui/associated-types/substs-ppaux.verbose.stderr
@@ -0,0 +1,89 @@
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:16:17
+ |
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>} defined here
+...
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
+help: use parentheses to call this function
+ |
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:25:17
+ |
+LL | fn bar<'a, T>() where T: 'a {}
+ | --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>} defined here
+...
+LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
+help: use parentheses to call this function
+ |
+LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:33:17
+ |
+LL | fn baz() {}
+ | -------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz} defined here
+...
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
+help: use parentheses to call this function
+ |
+LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz();
+ | ++
+
+error[E0308]: mismatched types
+ --> $DIR/substs-ppaux.rs:41:17
+ |
+LL | fn foo<'z>() where &'z (): Sized {
+ | -------------------------------- fn() {foo::<ReStatic>} defined here
+...
+LL | let x: () = foo::<'static>;
+ | -- ^^^^^^^^^^^^^^ expected `()`, found fn item
+ | |
+ | expected due to this
+ |
+ = note: expected unit type `()`
+ found fn item `fn() {foo::<ReStatic>}`
+help: use parentheses to call this function
+ |
+LL | let x: () = foo::<'static>();
+ | ++
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+ --> $DIR/substs-ppaux.rs:49:5
+ |
+LL | <str as Foo<u8>>::bar;
+ | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `str`
+note: required because of the requirements on the impl of `Foo<'_#0r, '_#1r, u8>` for `str`
+ --> $DIR/substs-ppaux.rs:11:17
+ |
+LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {}
+ | ^^^^^^^^^^^^^^ ^
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs
new file mode 100644
index 000000000..0474bf0a3
--- /dev/null
+++ b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs
@@ -0,0 +1,11 @@
+use std::ops::{Add, Sub, Mul, Div};
+
+trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> {}
+//~^ ERROR the size for values of type `Self` cannot be known at compilation time
+
+impl<T> ArithmeticOps for T where T: Add<Output=T> + Sub<Output=T> + Mul<Output=T> + Div<Output=T> {
+ // Nothing to implement, since T already supports the other traits.
+ // It has the functions it needs already
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr
new file mode 100644
index 000000000..0edc9a556
--- /dev/null
+++ b/src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the size for values of type `Self` cannot be known at compilation time
+ --> $DIR/trait-with-supertraits-needing-sized-self.rs:3:22
+ |
+LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> {}
+ | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+ |
+note: required by a bound in `Add`
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ |
+LL | pub trait Add<Rhs = Self> {
+ | ^^^^^^^^^^ required by this bound in `Add`
+help: consider further restricting `Self`
+ |
+LL | trait ArithmeticOps: Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> + Sized {}
+ | +++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/associated-types/wf-cycle-2.rs b/src/test/ui/associated-types/wf-cycle-2.rs
new file mode 100644
index 000000000..d7467ac22
--- /dev/null
+++ b/src/test/ui/associated-types/wf-cycle-2.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+trait IntoIt {
+ type Item;
+}
+
+impl<I> IntoIt for I {
+ type Item = ();
+}
+
+trait BaseGraph
+where
+ <Self::VertexIter as IntoIt>::Item: Sized,
+{
+ type VertexIter: IntoIt;
+}
+
+fn main() {}
diff --git a/src/test/ui/associated-types/wf-cycle.rs b/src/test/ui/associated-types/wf-cycle.rs
new file mode 100644
index 000000000..cf6508551
--- /dev/null
+++ b/src/test/ui/associated-types/wf-cycle.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+trait A {
+ type U: Copy;
+}
+
+trait B where
+ <Self::V as A>::U: Copy,
+{
+ type V: A;
+}
+
+fn main() {}