From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../associate-type-bound-normalization.rs | 25 ++ .../associated-types/associated-item-long-paths.rs | 47 ++++ .../associated-type-destructuring-assignment.rs | 10 + .../ui/associated-types/associated-type-macro.rs | 4 + .../associated-types/associated-type-macro.stderr | 8 + ...jection-ambig-between-bound-and-where-clause.rs | 42 ++++ ...ion-ambig-between-bound-and-where-clause.stderr | 129 ++++++++++ ...ed-type-projection-from-multiple-supertraits.rs | 43 ++++ ...ype-projection-from-multiple-supertraits.stderr | 100 ++++++++ .../associated-type-projection-from-supertrait.rs | 36 +++ ...sociated-type-projection-from-supertrait.stderr | 59 +++++ .../associated-type-struct-construction.rs | 24 ++ .../associated-type-tuple-struct-construction.rs | 24 ++ ...ssociated-type-tuple-struct-construction.stderr | 19 ++ ...ociated-types-ICE-when-projecting-out-of-err.rs | 25 ++ ...ted-types-ICE-when-projecting-out-of-err.stderr | 9 + .../ui/associated-types/associated-types-basic.rs | 14 ++ .../associated-types-binding-in-trait.rs | 36 +++ .../associated-types-binding-in-where-clause.rs | 38 +++ ...-types-binding-to-type-defined-in-supertrait.rs | 35 +++ ...es-binding-to-type-defined-in-supertrait.stderr | 37 +++ .../associated-types-bound-ambiguity.rs | 23 ++ .../associated-types-bound-failure.fixed | 29 +++ .../associated-types-bound-failure.rs | 29 +++ .../associated-types-bound-failure.stderr | 16 ++ .../ui/associated-types/associated-types-bound.rs | 43 ++++ .../ui/associated-types/associated-types-cc.rs | 18 ++ .../associated-types-coherence-failure.rs | 49 ++++ .../associated-types-coherence-failure.stderr | 21 ++ .../associated-types-conditional-dispatch.rs | 66 +++++ .../associated-types-constant-type.rs | 31 +++ .../associated-types-doubleendediterator-object.rs | 19 ++ ...sociated-types-duplicate-binding-in-env-hrtb.rs | 17 ++ .../associated-types-duplicate-binding-in-env.rs | 21 ++ .../associated-types-enum-field-named.rs | 35 +++ .../associated-types-enum-field-numbered.rs | 35 +++ .../ui/associated-types/associated-types-eq-1.rs | 13 + .../associated-types/associated-types-eq-1.stderr | 20 ++ .../ui/associated-types/associated-types-eq-2.rs | 19 ++ .../associated-types/associated-types-eq-2.stderr | 9 + .../ui/associated-types/associated-types-eq-3.rs | 42 ++++ .../associated-types/associated-types-eq-3.stderr | 49 ++++ .../associated-types-eq-expr-path.rs | 16 ++ .../associated-types-eq-expr-path.stderr | 9 + .../ui/associated-types/associated-types-eq-hr.rs | 111 +++++++++ .../associated-types/associated-types-eq-hr.stderr | 47 ++++ .../ui/associated-types/associated-types-eq-obj.rs | 25 ++ .../associated-types-for-unimpl-trait.fixed | 15 ++ .../associated-types-for-unimpl-trait.rs | 15 ++ .../associated-types-for-unimpl-trait.stderr | 14 ++ .../associated-types-from-supertrait.rs | 8 + .../associated-types-impl-redirect.rs | 51 ++++ .../associated-types-in-ambiguous-context.rs | 29 +++ .../associated-types-in-ambiguous-context.stderr | 33 +++ .../associated-types-in-bound-type-arg.rs | 17 ++ .../associated-types-in-default-method.rs | 27 +++ .../ui/associated-types/associated-types-in-fn.rs | 28 +++ .../associated-types-in-impl-generics.rs | 36 +++ .../associated-types-in-inherent-method.rs | 30 +++ .../associated-types-incomplete-object.rs | 31 +++ .../associated-types-incomplete-object.stderr | 32 +++ ...sociated-types-invalid-trait-ref-issue-18865.rs | 14 ++ ...ated-types-invalid-trait-ref-issue-18865.stderr | 14 ++ .../associated-types-issue-17359.rs | 10 + .../associated-types-issue-17359.stderr | 12 + .../associated-types-issue-20220.rs | 28 +++ .../associated-types-issue-20346.rs | 35 +++ .../associated-types-issue-20346.stderr | 25 ++ .../associated-types-issue-20371.rs | 9 + .../associated-types-issue-21212.rs | 22 ++ .../associated-types-iterator-binding.rs | 19 ++ .../ui/associated-types/associated-types-method.rs | 28 +++ .../associated-types-multiple-types-one-trait.rs | 46 ++++ ...ssociated-types-multiple-types-one-trait.stderr | 39 +++ .../associated-types-nested-projections.rs | 44 ++++ .../associated-types-no-suitable-bound.rs | 16 ++ .../associated-types-no-suitable-bound.stderr | 14 ++ .../associated-types-no-suitable-supertrait-2.rs | 21 ++ ...ssociated-types-no-suitable-supertrait-2.stderr | 14 ++ .../associated-types-no-suitable-supertrait.rs | 26 ++ .../associated-types-no-suitable-supertrait.stderr | 20 ++ ...associated-types-normalize-in-bounds-binding.rs | 38 +++ .../associated-types-normalize-in-bounds-ufcs.rs | 35 +++ .../associated-types-normalize-in-bounds.rs | 35 +++ .../associated-types-normalize-unifield-struct.rs | 24 ++ .../associated-types/associated-types-outlives.rs | 28 +++ .../associated-types-outlives.stderr | 13 + .../associated-types-overridden-binding-2.rs | 8 + .../associated-types-overridden-binding-2.stderr | 11 + .../associated-types-overridden-binding.rs | 11 + .../associated-types-overridden-binding.stderr | 27 +++ .../associated-types-overridden-default.rs | 22 ++ .../ui/associated-types/associated-types-path-1.rs | 13 + .../associated-types-path-1.stderr | 31 +++ .../ui/associated-types/associated-types-path-2.rs | 46 ++++ .../associated-types-path-2.stderr | 79 ++++++ ...ssociated-types-project-from-hrtb-in-fn-body.rs | 27 +++ ...iated-types-project-from-hrtb-in-fn-body.stderr | 30 +++ .../associated-types-project-from-hrtb-in-fn.fixed | 37 +++ .../associated-types-project-from-hrtb-in-fn.rs | 37 +++ ...associated-types-project-from-hrtb-in-fn.stderr | 14 ++ ...associated-types-project-from-hrtb-in-struct.rs | 39 +++ ...ciated-types-project-from-hrtb-in-struct.stderr | 54 +++++ ...d-types-project-from-hrtb-in-trait-method.fixed | 38 +++ ...ated-types-project-from-hrtb-in-trait-method.rs | 38 +++ ...-types-project-from-hrtb-in-trait-method.stderr | 25 ++ ...s-project-from-type-param-via-bound-in-where.rs | 98 ++++++++ .../associated-types-projection-bound-ambiguity.rs | 16 ++ ...ciated-types-projection-bound-in-supertraits.rs | 23 ++ ...ted-types-projection-from-known-type-in-impl.rs | 38 +++ .../associated-types-projection-in-object-type.rs | 40 ++++ .../associated-types-projection-in-supertrait.rs | 45 ++++ .../associated-types-projection-in-where-clause.rs | 31 +++ ...unrelated-trait-in-method-without-default.fixed | 30 +++ ...to-unrelated-trait-in-method-without-default.rs | 30 +++ ...nrelated-trait-in-method-without-default.stderr | 14 ++ ...sociated-types-projection-to-unrelated-trait.rs | 35 +++ ...alified-path-with-trait-with-type-parameters.rs | 9 + .../associated-types-ref-from-struct.rs | 51 ++++ .../associated-types-ref-in-struct-literal.rs | 23 ++ .../associated-types-region-erasure-issue-20582.rs | 21 ++ .../associated-types-resolve-lifetime.rs | 15 ++ .../ui/associated-types/associated-types-return.rs | 46 ++++ .../ui/associated-types/associated-types-simple.rs | 24 ++ .../ui/associated-types/associated-types-stream.rs | 38 +++ .../associated-types-struct-field-named.rs | 35 +++ .../associated-types-struct-field-numbered.rs | 32 +++ .../associated-types-subtyping-1.rs | 49 ++++ .../associated-types-subtyping-1.stderr | 28 +++ .../associated-types-sugar-path.rs | 41 ++++ .../associated-types-unconstrained.rs | 16 ++ .../associated-types-unconstrained.stderr | 12 + .../associated-types-unsized.fixed | 14 ++ .../associated-types/associated-types-unsized.rs | 14 ++ .../associated-types-unsized.stderr | 17 ++ ...associated-types-where-clause-impl-ambiguity.rs | 46 ++++ .../auxiliary/associated-types-cc-lib.rs | 16 ++ .../bound-lifetime-constrained.clause.stderr | 15 ++ .../bound-lifetime-constrained.func.stderr | 15 ++ .../bound-lifetime-constrained.object.stderr | 15 ++ .../associated-types/bound-lifetime-constrained.rs | 48 ++++ .../bound-lifetime-in-binding-only.angle.stderr | 27 +++ .../bound-lifetime-in-binding-only.elision.stderr | 15 ++ .../bound-lifetime-in-binding-only.ok.stderr | 8 + .../bound-lifetime-in-binding-only.paren.stderr | 27 +++ .../bound-lifetime-in-binding-only.rs | 71 ++++++ .../bound-lifetime-in-return-only.elision.stderr | 15 ++ .../bound-lifetime-in-return-only.local.stderr | 9 + .../bound-lifetime-in-return-only.ok.stderr | 8 + .../bound-lifetime-in-return-only.rs | 49 ++++ .../bound-lifetime-in-return-only.sig.stderr | 15 ++ .../bound-lifetime-in-return-only.structure.stderr | 9 + src/test/ui/associated-types/cache/chrono-scan.rs | 30 +++ src/test/ui/associated-types/cache/elision.rs | 23 ++ .../project-fn-ret-contravariant.krisskross.stderr | 30 +++ .../cache/project-fn-ret-contravariant.rs | 50 ++++ .../project-fn-ret-contravariant.transmute.stderr | 10 + .../project-fn-ret-invariant.krisskross.stderr | 36 +++ .../cache/project-fn-ret-invariant.oneuse.stderr | 36 +++ .../cache/project-fn-ret-invariant.rs | 64 +++++ .../project-fn-ret-invariant.transmute.stderr | 15 ++ .../associated-types/default-associated-types.rs | 23 ++ .../ui/associated-types/defaults-cyclic-fail-1.rs | 40 ++++ .../associated-types/defaults-cyclic-fail-1.stderr | 15 ++ .../ui/associated-types/defaults-cyclic-fail-2.rs | 41 ++++ .../associated-types/defaults-cyclic-fail-2.stderr | 15 ++ .../ui/associated-types/defaults-cyclic-pass-1.rs | 56 +++++ .../ui/associated-types/defaults-cyclic-pass-2.rs | 56 +++++ .../defaults-in-other-trait-items-pass.rs | 37 +++ .../defaults-in-other-trait-items.rs | 47 ++++ .../defaults-in-other-trait-items.stderr | 29 +++ src/test/ui/associated-types/defaults-mixed.rs | 34 +++ src/test/ui/associated-types/defaults-mixed.stderr | 21 ++ .../ui/associated-types/defaults-specialization.rs | 96 ++++++++ .../defaults-specialization.stderr | 156 ++++++++++++ .../ui/associated-types/defaults-suitability.rs | 101 ++++++++ .../associated-types/defaults-suitability.stderr | 135 +++++++++++ .../associated-types/defaults-unsound-62211-1.rs | 54 +++++ .../defaults-unsound-62211-1.stderr | 68 ++++++ .../associated-types/defaults-unsound-62211-2.rs | 54 +++++ .../defaults-unsound-62211-2.stderr | 68 ++++++ src/test/ui/associated-types/defaults-wf.rs | 11 + src/test/ui/associated-types/defaults-wf.stderr | 16 ++ .../higher-ranked-projection.bad.stderr | 17 ++ .../higher-ranked-projection.badbase.stderr | 17 ++ .../higher-ranked-projection.badnll.stderr | 2 + .../associated-types/higher-ranked-projection.rs | 25 ++ .../associated-types/hr-associated-type-bound-1.rs | 18 ++ .../hr-associated-type-bound-1.stderr | 19 ++ .../associated-types/hr-associated-type-bound-2.rs | 20 ++ .../hr-associated-type-bound-2.stderr | 18 ++ .../hr-associated-type-bound-object.rs | 14 ++ .../hr-associated-type-bound-object.stderr | 18 ++ .../hr-associated-type-bound-param-1.rs | 20 ++ .../hr-associated-type-bound-param-1.stderr | 19 ++ .../hr-associated-type-bound-param-2.rs | 21 ++ .../hr-associated-type-bound-param-2.stderr | 51 ++++ .../hr-associated-type-bound-param-3.rs | 19 ++ .../hr-associated-type-bound-param-3.stderr | 19 ++ .../hr-associated-type-bound-param-4.rs | 19 ++ .../hr-associated-type-bound-param-4.stderr | 19 ++ .../hr-associated-type-bound-param-5.rs | 37 +++ .../hr-associated-type-bound-param-5.stderr | 35 +++ .../hr-associated-type-bound-param-6.rs | 19 ++ .../hr-associated-type-bound-param-6.stderr | 14 ++ .../hr-associated-type-projection-1.rs | 20 ++ .../hr-associated-type-projection-1.stderr | 24 ++ .../impl-trait-return-missing-constraint.rs | 32 +++ .../impl-trait-return-missing-constraint.stderr | 24 ++ src/test/ui/associated-types/impl-wf-cycle-1.rs | 27 +++ .../ui/associated-types/impl-wf-cycle-1.stderr | 17 ++ src/test/ui/associated-types/impl-wf-cycle-2.rs | 15 ++ .../ui/associated-types/impl-wf-cycle-2.stderr | 15 ++ src/test/ui/associated-types/issue-18655.rs | 22 ++ src/test/ui/associated-types/issue-19081.rs | 14 ++ src/test/ui/associated-types/issue-19883.rs | 16 ++ src/test/ui/associated-types/issue-19883.stderr | 15 ++ src/test/ui/associated-types/issue-20005.rs | 15 ++ src/test/ui/associated-types/issue-20005.stderr | 23 ++ src/test/ui/associated-types/issue-20825-2.rs | 10 + src/test/ui/associated-types/issue-20825.rs | 10 + src/test/ui/associated-types/issue-20825.stderr | 16 ++ src/test/ui/associated-types/issue-21363.rs | 15 ++ src/test/ui/associated-types/issue-21726.rs | 38 +++ src/test/ui/associated-types/issue-22037.rs | 17 ++ src/test/ui/associated-types/issue-22037.stderr | 14 ++ src/test/ui/associated-types/issue-22066.rs | 12 + src/test/ui/associated-types/issue-22560.rs | 15 ++ src/test/ui/associated-types/issue-22560.stderr | 56 +++++ src/test/ui/associated-types/issue-22828.rs | 23 ++ src/test/ui/associated-types/issue-23208.rs | 26 ++ src/test/ui/associated-types/issue-23595-1.rs | 14 ++ src/test/ui/associated-types/issue-23595-1.stderr | 13 + src/test/ui/associated-types/issue-23595-2.rs | 10 + src/test/ui/associated-types/issue-23595-2.stderr | 9 + src/test/ui/associated-types/issue-24159.rs | 37 +++ src/test/ui/associated-types/issue-24204.rs | 25 ++ src/test/ui/associated-types/issue-24338.rs | 21 ++ src/test/ui/associated-types/issue-25339.rs | 31 +++ src/test/ui/associated-types/issue-26681.rs | 20 ++ src/test/ui/associated-types/issue-26681.stderr | 14 ++ .../issue-27675-unchecked-bounds.rs | 19 ++ .../issue-27675-unchecked-bounds.stderr | 21 ++ src/test/ui/associated-types/issue-28871.rs | 24 ++ src/test/ui/associated-types/issue-31597.rs | 29 +++ src/test/ui/associated-types/issue-32350.rs | 29 +++ src/test/ui/associated-types/issue-36499.rs | 5 + src/test/ui/associated-types/issue-36499.stderr | 14 ++ src/test/ui/associated-types/issue-37808.rs | 19 ++ src/test/ui/associated-types/issue-37883.rs | 25 ++ src/test/ui/associated-types/issue-38917.rs | 25 ++ src/test/ui/associated-types/issue-39532.rs | 14 ++ src/test/ui/associated-types/issue-40093.rs | 14 ++ src/test/ui/associated-types/issue-41868.rs | 23 ++ src/test/ui/associated-types/issue-43475.rs | 10 + .../issue-43784-associated-type.rs | 17 ++ .../issue-43784-associated-type.stderr | 19 ++ src/test/ui/associated-types/issue-43924.rs | 16 ++ src/test/ui/associated-types/issue-43924.stderr | 22 ++ src/test/ui/associated-types/issue-44153.rs | 19 ++ src/test/ui/associated-types/issue-44153.stderr | 20 ++ src/test/ui/associated-types/issue-47139-1.rs | 78 ++++++ src/test/ui/associated-types/issue-47139-2.rs | 66 +++++ src/test/ui/associated-types/issue-47385.rs | 16 ++ src/test/ui/associated-types/issue-47814.rs | 13 + src/test/ui/associated-types/issue-47814.stderr | 14 ++ src/test/ui/associated-types/issue-48010.rs | 23 ++ src/test/ui/associated-types/issue-48551.rs | 34 +++ src/test/ui/associated-types/issue-50301.rs | 31 +++ src/test/ui/associated-types/issue-54108.rs | 41 ++++ src/test/ui/associated-types/issue-54108.stderr | 20 ++ src/test/ui/associated-types/issue-54182-1.rs | 92 +++++++ src/test/ui/associated-types/issue-54182-2.rs | 19 ++ src/test/ui/associated-types/issue-54467.rs | 46 ++++ src/test/ui/associated-types/issue-55846.rs | 39 +++ src/test/ui/associated-types/issue-59324.rs | 26 ++ src/test/ui/associated-types/issue-59324.stderr | 65 +++++ src/test/ui/associated-types/issue-62200.rs | 15 ++ src/test/ui/associated-types/issue-62200.stderr | 11 + src/test/ui/associated-types/issue-63591.rs | 24 ++ src/test/ui/associated-types/issue-63593.rs | 13 + src/test/ui/associated-types/issue-63593.stderr | 19 ++ src/test/ui/associated-types/issue-64848.rs | 29 +++ src/test/ui/associated-types/issue-64855-2.rs | 5 + src/test/ui/associated-types/issue-64855.rs | 8 + src/test/ui/associated-types/issue-64855.stderr | 9 + src/test/ui/associated-types/issue-65774-1.rs | 58 +++++ src/test/ui/associated-types/issue-65774-1.stderr | 30 +++ src/test/ui/associated-types/issue-65774-2.rs | 58 +++++ src/test/ui/associated-types/issue-65774-2.stderr | 25 ++ src/test/ui/associated-types/issue-65934.rs | 17 ++ src/test/ui/associated-types/issue-67684.rs | 62 +++++ src/test/ui/associated-types/issue-69398.rs | 21 ++ src/test/ui/associated-types/issue-71113.rs | 16 ++ src/test/ui/associated-types/issue-72806.rs | 21 ++ src/test/ui/associated-types/issue-72806.stderr | 20 ++ src/test/ui/associated-types/issue-76179.rs | 19 ++ src/test/ui/associated-types/issue-82079.rs | 124 ++++++++++ src/test/ui/associated-types/issue-85103.rs | 9 + src/test/ui/associated-types/issue-85103.stderr | 8 + src/test/ui/associated-types/issue-87261.rs | 99 ++++++++ src/test/ui/associated-types/issue-87261.stderr | 266 +++++++++++++++++++++ src/test/ui/associated-types/issue-88856.rs | 32 +++ src/test/ui/associated-types/issue-91069.rs | 24 ++ src/test/ui/associated-types/issue-91231.rs | 17 ++ src/test/ui/associated-types/issue-91234.rs | 13 + .../associated-types/missing-associated-types.rs | 27 +++ .../missing-associated-types.stderr | 129 ++++++++++ .../associated-types/normalization-debruijn-1.rs | 36 +++ .../associated-types/normalization-debruijn-2.rs | 31 +++ .../associated-types/normalization-debruijn-3.rs | 41 ++++ .../associated-types/normalization-generality-2.rs | 30 +++ .../associated-types/normalization-generality.rs | 36 +++ .../associated-types/normalization-probe-cycle.rs | 25 ++ .../normalize-cycle-in-eval-no-region.rs | 20 ++ .../ui/associated-types/normalize-cycle-in-eval.rs | 43 ++++ .../ui/associated-types/object-method-numbering.rs | 28 +++ .../ui/associated-types/object-normalization.rs | 26 ++ .../associated-types/param-env-normalize-cycle.rs | 39 +++ .../point-at-type-on-obligation-failure-2.rs | 33 +++ .../point-at-type-on-obligation-failure-2.stderr | 45 ++++ .../point-at-type-on-obligation-failure.rs | 21 ++ .../point-at-type-on-obligation-failure.stderr | 20 ++ .../associated-types/project-defer-unification.rs | 104 ++++++++ .../project-recursion-limit-non-fatal.rs | 58 +++++ .../ui/associated-types/substs-ppaux.normal.stderr | 89 +++++++ src/test/ui/associated-types/substs-ppaux.rs | 52 ++++ .../associated-types/substs-ppaux.verbose.stderr | 89 +++++++ .../trait-with-supertraits-needing-sized-self.rs | 11 + ...rait-with-supertraits-needing-sized-self.stderr | 19 ++ src/test/ui/associated-types/wf-cycle-2.rs | 18 ++ src/test/ui/associated-types/wf-cycle.rs | 13 + 332 files changed, 10265 insertions(+) create mode 100644 src/test/ui/associated-types/associate-type-bound-normalization.rs create mode 100644 src/test/ui/associated-types/associated-item-long-paths.rs create mode 100644 src/test/ui/associated-types/associated-type-destructuring-assignment.rs create mode 100644 src/test/ui/associated-types/associated-type-macro.rs create mode 100644 src/test/ui/associated-types/associated-type-macro.stderr create mode 100644 src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.rs create mode 100644 src/test/ui/associated-types/associated-type-projection-ambig-between-bound-and-where-clause.stderr create mode 100644 src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs create mode 100644 src/test/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr create mode 100644 src/test/ui/associated-types/associated-type-projection-from-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr create mode 100644 src/test/ui/associated-types/associated-type-struct-construction.rs create mode 100644 src/test/ui/associated-types/associated-type-tuple-struct-construction.rs create mode 100644 src/test/ui/associated-types/associated-type-tuple-struct-construction.stderr create mode 100644 src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.rs create mode 100644 src/test/ui/associated-types/associated-types-ICE-when-projecting-out-of-err.stderr create mode 100644 src/test/ui/associated-types/associated-types-basic.rs create mode 100644 src/test/ui/associated-types/associated-types-binding-in-trait.rs create mode 100644 src/test/ui/associated-types/associated-types-binding-in-where-clause.rs create mode 100644 src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr create mode 100644 src/test/ui/associated-types/associated-types-bound-ambiguity.rs create mode 100644 src/test/ui/associated-types/associated-types-bound-failure.fixed create mode 100644 src/test/ui/associated-types/associated-types-bound-failure.rs create mode 100644 src/test/ui/associated-types/associated-types-bound-failure.stderr create mode 100644 src/test/ui/associated-types/associated-types-bound.rs create mode 100644 src/test/ui/associated-types/associated-types-cc.rs create mode 100644 src/test/ui/associated-types/associated-types-coherence-failure.rs create mode 100644 src/test/ui/associated-types/associated-types-coherence-failure.stderr create mode 100644 src/test/ui/associated-types/associated-types-conditional-dispatch.rs create mode 100644 src/test/ui/associated-types/associated-types-constant-type.rs create mode 100644 src/test/ui/associated-types/associated-types-doubleendediterator-object.rs create mode 100644 src/test/ui/associated-types/associated-types-duplicate-binding-in-env-hrtb.rs create mode 100644 src/test/ui/associated-types/associated-types-duplicate-binding-in-env.rs create mode 100644 src/test/ui/associated-types/associated-types-enum-field-named.rs create mode 100644 src/test/ui/associated-types/associated-types-enum-field-numbered.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-1.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-1.stderr create mode 100644 src/test/ui/associated-types/associated-types-eq-2.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-2.stderr create mode 100644 src/test/ui/associated-types/associated-types-eq-3.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-3.stderr create mode 100644 src/test/ui/associated-types/associated-types-eq-expr-path.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-expr-path.stderr create mode 100644 src/test/ui/associated-types/associated-types-eq-hr.rs create mode 100644 src/test/ui/associated-types/associated-types-eq-hr.stderr create mode 100644 src/test/ui/associated-types/associated-types-eq-obj.rs create mode 100644 src/test/ui/associated-types/associated-types-for-unimpl-trait.fixed create mode 100644 src/test/ui/associated-types/associated-types-for-unimpl-trait.rs create mode 100644 src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr create mode 100644 src/test/ui/associated-types/associated-types-from-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-types-impl-redirect.rs create mode 100644 src/test/ui/associated-types/associated-types-in-ambiguous-context.rs create mode 100644 src/test/ui/associated-types/associated-types-in-ambiguous-context.stderr create mode 100644 src/test/ui/associated-types/associated-types-in-bound-type-arg.rs create mode 100644 src/test/ui/associated-types/associated-types-in-default-method.rs create mode 100644 src/test/ui/associated-types/associated-types-in-fn.rs create mode 100644 src/test/ui/associated-types/associated-types-in-impl-generics.rs create mode 100644 src/test/ui/associated-types/associated-types-in-inherent-method.rs create mode 100644 src/test/ui/associated-types/associated-types-incomplete-object.rs create mode 100644 src/test/ui/associated-types/associated-types-incomplete-object.stderr create mode 100644 src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.rs create mode 100644 src/test/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr create mode 100644 src/test/ui/associated-types/associated-types-issue-17359.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-17359.stderr create mode 100644 src/test/ui/associated-types/associated-types-issue-20220.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-20346.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-20346.stderr create mode 100644 src/test/ui/associated-types/associated-types-issue-20371.rs create mode 100644 src/test/ui/associated-types/associated-types-issue-21212.rs create mode 100644 src/test/ui/associated-types/associated-types-iterator-binding.rs create mode 100644 src/test/ui/associated-types/associated-types-method.rs create mode 100644 src/test/ui/associated-types/associated-types-multiple-types-one-trait.rs create mode 100644 src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr create mode 100644 src/test/ui/associated-types/associated-types-nested-projections.rs create mode 100644 src/test/ui/associated-types/associated-types-no-suitable-bound.rs create mode 100644 src/test/ui/associated-types/associated-types-no-suitable-bound.stderr create mode 100644 src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.rs create mode 100644 src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr create mode 100644 src/test/ui/associated-types/associated-types-no-suitable-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr create mode 100644 src/test/ui/associated-types/associated-types-normalize-in-bounds-binding.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-in-bounds.rs create mode 100644 src/test/ui/associated-types/associated-types-normalize-unifield-struct.rs create mode 100644 src/test/ui/associated-types/associated-types-outlives.rs create mode 100644 src/test/ui/associated-types/associated-types-outlives.stderr create mode 100644 src/test/ui/associated-types/associated-types-overridden-binding-2.rs create mode 100644 src/test/ui/associated-types/associated-types-overridden-binding-2.stderr create mode 100644 src/test/ui/associated-types/associated-types-overridden-binding.rs create mode 100644 src/test/ui/associated-types/associated-types-overridden-binding.stderr create mode 100644 src/test/ui/associated-types/associated-types-overridden-default.rs create mode 100644 src/test/ui/associated-types/associated-types-path-1.rs create mode 100644 src/test/ui/associated-types/associated-types-path-1.stderr create mode 100644 src/test/ui/associated-types/associated-types-path-2.rs create mode 100644 src/test/ui/associated-types/associated-types-path-2.stderr create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.rs create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn-body.stderr create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.fixed create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.rs create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-fn.stderr create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.rs create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-struct.stderr create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.fixed create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.rs create mode 100644 src/test/ui/associated-types/associated-types-project-from-hrtb-in-trait-method.stderr create mode 100644 src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-bound-ambiguity.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-bound-in-supertraits.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-in-object-type.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-in-supertrait.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-in-where-clause.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed create mode 100644 src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs create mode 100644 src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr create mode 100644 src/test/ui/associated-types/associated-types-projection-to-unrelated-trait.rs create mode 100644 src/test/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs create mode 100644 src/test/ui/associated-types/associated-types-ref-from-struct.rs create mode 100644 src/test/ui/associated-types/associated-types-ref-in-struct-literal.rs create mode 100644 src/test/ui/associated-types/associated-types-region-erasure-issue-20582.rs create mode 100644 src/test/ui/associated-types/associated-types-resolve-lifetime.rs create mode 100644 src/test/ui/associated-types/associated-types-return.rs create mode 100644 src/test/ui/associated-types/associated-types-simple.rs create mode 100644 src/test/ui/associated-types/associated-types-stream.rs create mode 100644 src/test/ui/associated-types/associated-types-struct-field-named.rs create mode 100644 src/test/ui/associated-types/associated-types-struct-field-numbered.rs create mode 100644 src/test/ui/associated-types/associated-types-subtyping-1.rs create mode 100644 src/test/ui/associated-types/associated-types-subtyping-1.stderr create mode 100644 src/test/ui/associated-types/associated-types-sugar-path.rs create mode 100644 src/test/ui/associated-types/associated-types-unconstrained.rs create mode 100644 src/test/ui/associated-types/associated-types-unconstrained.stderr create mode 100644 src/test/ui/associated-types/associated-types-unsized.fixed create mode 100644 src/test/ui/associated-types/associated-types-unsized.rs create mode 100644 src/test/ui/associated-types/associated-types-unsized.stderr create mode 100644 src/test/ui/associated-types/associated-types-where-clause-impl-ambiguity.rs create mode 100644 src/test/ui/associated-types/auxiliary/associated-types-cc-lib.rs create mode 100644 src/test/ui/associated-types/bound-lifetime-constrained.clause.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-constrained.func.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-constrained.object.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-constrained.rs create mode 100644 src/test/ui/associated-types/bound-lifetime-in-binding-only.angle.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-binding-only.elision.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-binding-only.paren.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-binding-only.rs create mode 100644 src/test/ui/associated-types/bound-lifetime-in-return-only.elision.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-return-only.local.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-return-only.rs create mode 100644 src/test/ui/associated-types/bound-lifetime-in-return-only.sig.stderr create mode 100644 src/test/ui/associated-types/bound-lifetime-in-return-only.structure.stderr create mode 100644 src/test/ui/associated-types/cache/chrono-scan.rs create mode 100644 src/test/ui/associated-types/cache/elision.rs create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.rs create mode 100644 src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr create mode 100644 src/test/ui/associated-types/default-associated-types.rs create mode 100644 src/test/ui/associated-types/defaults-cyclic-fail-1.rs create mode 100644 src/test/ui/associated-types/defaults-cyclic-fail-1.stderr create mode 100644 src/test/ui/associated-types/defaults-cyclic-fail-2.rs create mode 100644 src/test/ui/associated-types/defaults-cyclic-fail-2.stderr create mode 100644 src/test/ui/associated-types/defaults-cyclic-pass-1.rs create mode 100644 src/test/ui/associated-types/defaults-cyclic-pass-2.rs create mode 100644 src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs create mode 100644 src/test/ui/associated-types/defaults-in-other-trait-items.rs create mode 100644 src/test/ui/associated-types/defaults-in-other-trait-items.stderr create mode 100644 src/test/ui/associated-types/defaults-mixed.rs create mode 100644 src/test/ui/associated-types/defaults-mixed.stderr create mode 100644 src/test/ui/associated-types/defaults-specialization.rs create mode 100644 src/test/ui/associated-types/defaults-specialization.stderr create mode 100644 src/test/ui/associated-types/defaults-suitability.rs create mode 100644 src/test/ui/associated-types/defaults-suitability.stderr create mode 100644 src/test/ui/associated-types/defaults-unsound-62211-1.rs create mode 100644 src/test/ui/associated-types/defaults-unsound-62211-1.stderr create mode 100644 src/test/ui/associated-types/defaults-unsound-62211-2.rs create mode 100644 src/test/ui/associated-types/defaults-unsound-62211-2.stderr create mode 100644 src/test/ui/associated-types/defaults-wf.rs create mode 100644 src/test/ui/associated-types/defaults-wf.stderr create mode 100644 src/test/ui/associated-types/higher-ranked-projection.bad.stderr create mode 100644 src/test/ui/associated-types/higher-ranked-projection.badbase.stderr create mode 100644 src/test/ui/associated-types/higher-ranked-projection.badnll.stderr create mode 100644 src/test/ui/associated-types/higher-ranked-projection.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-1.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-1.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-2.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-2.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-object.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-object.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-1.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-1.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-2.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-2.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-3.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-3.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-4.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-4.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-5.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-5.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-6.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-bound-param-6.stderr create mode 100644 src/test/ui/associated-types/hr-associated-type-projection-1.rs create mode 100644 src/test/ui/associated-types/hr-associated-type-projection-1.stderr create mode 100644 src/test/ui/associated-types/impl-trait-return-missing-constraint.rs create mode 100644 src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr create mode 100644 src/test/ui/associated-types/impl-wf-cycle-1.rs create mode 100644 src/test/ui/associated-types/impl-wf-cycle-1.stderr create mode 100644 src/test/ui/associated-types/impl-wf-cycle-2.rs create mode 100644 src/test/ui/associated-types/impl-wf-cycle-2.stderr create mode 100644 src/test/ui/associated-types/issue-18655.rs create mode 100644 src/test/ui/associated-types/issue-19081.rs create mode 100644 src/test/ui/associated-types/issue-19883.rs create mode 100644 src/test/ui/associated-types/issue-19883.stderr create mode 100644 src/test/ui/associated-types/issue-20005.rs create mode 100644 src/test/ui/associated-types/issue-20005.stderr create mode 100644 src/test/ui/associated-types/issue-20825-2.rs create mode 100644 src/test/ui/associated-types/issue-20825.rs create mode 100644 src/test/ui/associated-types/issue-20825.stderr create mode 100644 src/test/ui/associated-types/issue-21363.rs create mode 100644 src/test/ui/associated-types/issue-21726.rs create mode 100644 src/test/ui/associated-types/issue-22037.rs create mode 100644 src/test/ui/associated-types/issue-22037.stderr create mode 100644 src/test/ui/associated-types/issue-22066.rs create mode 100644 src/test/ui/associated-types/issue-22560.rs create mode 100644 src/test/ui/associated-types/issue-22560.stderr create mode 100644 src/test/ui/associated-types/issue-22828.rs create mode 100644 src/test/ui/associated-types/issue-23208.rs create mode 100644 src/test/ui/associated-types/issue-23595-1.rs create mode 100644 src/test/ui/associated-types/issue-23595-1.stderr create mode 100644 src/test/ui/associated-types/issue-23595-2.rs create mode 100644 src/test/ui/associated-types/issue-23595-2.stderr create mode 100644 src/test/ui/associated-types/issue-24159.rs create mode 100644 src/test/ui/associated-types/issue-24204.rs create mode 100644 src/test/ui/associated-types/issue-24338.rs create mode 100644 src/test/ui/associated-types/issue-25339.rs create mode 100644 src/test/ui/associated-types/issue-26681.rs create mode 100644 src/test/ui/associated-types/issue-26681.stderr create mode 100644 src/test/ui/associated-types/issue-27675-unchecked-bounds.rs create mode 100644 src/test/ui/associated-types/issue-27675-unchecked-bounds.stderr create mode 100644 src/test/ui/associated-types/issue-28871.rs create mode 100644 src/test/ui/associated-types/issue-31597.rs create mode 100644 src/test/ui/associated-types/issue-32350.rs create mode 100644 src/test/ui/associated-types/issue-36499.rs create mode 100644 src/test/ui/associated-types/issue-36499.stderr create mode 100644 src/test/ui/associated-types/issue-37808.rs create mode 100644 src/test/ui/associated-types/issue-37883.rs create mode 100644 src/test/ui/associated-types/issue-38917.rs create mode 100644 src/test/ui/associated-types/issue-39532.rs create mode 100644 src/test/ui/associated-types/issue-40093.rs create mode 100644 src/test/ui/associated-types/issue-41868.rs create mode 100644 src/test/ui/associated-types/issue-43475.rs create mode 100644 src/test/ui/associated-types/issue-43784-associated-type.rs create mode 100644 src/test/ui/associated-types/issue-43784-associated-type.stderr create mode 100644 src/test/ui/associated-types/issue-43924.rs create mode 100644 src/test/ui/associated-types/issue-43924.stderr create mode 100644 src/test/ui/associated-types/issue-44153.rs create mode 100644 src/test/ui/associated-types/issue-44153.stderr create mode 100644 src/test/ui/associated-types/issue-47139-1.rs create mode 100644 src/test/ui/associated-types/issue-47139-2.rs create mode 100644 src/test/ui/associated-types/issue-47385.rs create mode 100644 src/test/ui/associated-types/issue-47814.rs create mode 100644 src/test/ui/associated-types/issue-47814.stderr create mode 100644 src/test/ui/associated-types/issue-48010.rs create mode 100644 src/test/ui/associated-types/issue-48551.rs create mode 100644 src/test/ui/associated-types/issue-50301.rs create mode 100644 src/test/ui/associated-types/issue-54108.rs create mode 100644 src/test/ui/associated-types/issue-54108.stderr create mode 100644 src/test/ui/associated-types/issue-54182-1.rs create mode 100644 src/test/ui/associated-types/issue-54182-2.rs create mode 100644 src/test/ui/associated-types/issue-54467.rs create mode 100644 src/test/ui/associated-types/issue-55846.rs create mode 100644 src/test/ui/associated-types/issue-59324.rs create mode 100644 src/test/ui/associated-types/issue-59324.stderr create mode 100644 src/test/ui/associated-types/issue-62200.rs create mode 100644 src/test/ui/associated-types/issue-62200.stderr create mode 100644 src/test/ui/associated-types/issue-63591.rs create mode 100644 src/test/ui/associated-types/issue-63593.rs create mode 100644 src/test/ui/associated-types/issue-63593.stderr create mode 100644 src/test/ui/associated-types/issue-64848.rs create mode 100644 src/test/ui/associated-types/issue-64855-2.rs create mode 100644 src/test/ui/associated-types/issue-64855.rs create mode 100644 src/test/ui/associated-types/issue-64855.stderr create mode 100644 src/test/ui/associated-types/issue-65774-1.rs create mode 100644 src/test/ui/associated-types/issue-65774-1.stderr create mode 100644 src/test/ui/associated-types/issue-65774-2.rs create mode 100644 src/test/ui/associated-types/issue-65774-2.stderr create mode 100644 src/test/ui/associated-types/issue-65934.rs create mode 100644 src/test/ui/associated-types/issue-67684.rs create mode 100644 src/test/ui/associated-types/issue-69398.rs create mode 100644 src/test/ui/associated-types/issue-71113.rs create mode 100644 src/test/ui/associated-types/issue-72806.rs create mode 100644 src/test/ui/associated-types/issue-72806.stderr create mode 100644 src/test/ui/associated-types/issue-76179.rs create mode 100644 src/test/ui/associated-types/issue-82079.rs create mode 100644 src/test/ui/associated-types/issue-85103.rs create mode 100644 src/test/ui/associated-types/issue-85103.stderr create mode 100644 src/test/ui/associated-types/issue-87261.rs create mode 100644 src/test/ui/associated-types/issue-87261.stderr create mode 100644 src/test/ui/associated-types/issue-88856.rs create mode 100644 src/test/ui/associated-types/issue-91069.rs create mode 100644 src/test/ui/associated-types/issue-91231.rs create mode 100644 src/test/ui/associated-types/issue-91234.rs create mode 100644 src/test/ui/associated-types/missing-associated-types.rs create mode 100644 src/test/ui/associated-types/missing-associated-types.stderr create mode 100644 src/test/ui/associated-types/normalization-debruijn-1.rs create mode 100644 src/test/ui/associated-types/normalization-debruijn-2.rs create mode 100644 src/test/ui/associated-types/normalization-debruijn-3.rs create mode 100644 src/test/ui/associated-types/normalization-generality-2.rs create mode 100644 src/test/ui/associated-types/normalization-generality.rs create mode 100644 src/test/ui/associated-types/normalization-probe-cycle.rs create mode 100644 src/test/ui/associated-types/normalize-cycle-in-eval-no-region.rs create mode 100644 src/test/ui/associated-types/normalize-cycle-in-eval.rs create mode 100644 src/test/ui/associated-types/object-method-numbering.rs create mode 100644 src/test/ui/associated-types/object-normalization.rs create mode 100644 src/test/ui/associated-types/param-env-normalize-cycle.rs create mode 100644 src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs create mode 100644 src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr create mode 100644 src/test/ui/associated-types/point-at-type-on-obligation-failure.rs create mode 100644 src/test/ui/associated-types/point-at-type-on-obligation-failure.stderr create mode 100644 src/test/ui/associated-types/project-defer-unification.rs create mode 100644 src/test/ui/associated-types/project-recursion-limit-non-fatal.rs create mode 100644 src/test/ui/associated-types/substs-ppaux.normal.stderr create mode 100644 src/test/ui/associated-types/substs-ppaux.rs create mode 100644 src/test/ui/associated-types/substs-ppaux.verbose.stderr create mode 100644 src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.rs create mode 100644 src/test/ui/associated-types/trait-with-supertraits-needing-sized-self.stderr create mode 100644 src/test/ui/associated-types/wf-cycle-2.rs create mode 100644 src/test/ui/associated-types/wf-cycle.rs (limited to 'src/test/ui/associated-types') 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 { + type Output; +} + +trait Matrix: Mul<::Row, Output = ()> { + type Row; + + type Transpose: Matrix; +} + +fn is_mul>() {} + +fn f() { + // The unnormalized bound on `T::Transpose` is + // `Mul<::Row` which has to be normalized to be + // equal to `T::Row`. + is_mul::(); +} + +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() -> usize; +} + +struct MyFoo; +struct MyBar; + +impl Foo for MyFoo { + type U = MyBar; +} + +impl Bar for MyBar { + fn method() -> u32 { + 2u32 + } + fn generic_method() -> usize { + size_of::() + } +} + +fn foo() + where T: Foo, + T::U: Bar, +{ + assert_eq!(2u32, ::U::method()); + assert_eq!(8usize, ::U::generic_method::()); +} + +fn main() { + foo::(); +} 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() { + ::V() = E::V(); // OK, destructuring assignment + ::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::Color) { + //~^ ERROR ambiguous associated type `Color` in bounds of `C` +} + +fn b(_: C::Color) where C : Vehicle+Box { + //~^ ERROR ambiguous associated type `Color` in bounds of `C` +} + +fn c(_: C::Color) where C : Vehicle, C : Box { + //~^ ERROR ambiguous associated type `Color` in bounds of `C` +} + +struct D; +impl D where X : Vehicle { + fn d(&self, _: X::Color) where X : Box { } + //~^ ERROR ambiguous associated type `Color` in bounds of `X` +} + +trait E { + 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::Color) { + | ^^^^^^^^ ambiguous associated type `Color` + | +help: use fully qualified syntax to disambiguate + | +LL | fn a(_: ::Color) { + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn a(_: ::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::Color) where C : Vehicle+Box { + | ^^^^^^^^ ambiguous associated type `Color` + | +help: use fully qualified syntax to disambiguate + | +LL | fn b(_: ::Color) where C : Vehicle+Box { + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn b(_: ::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::Color) where C : Vehicle, C : Box { + | ^^^^^^^^ ambiguous associated type `Color` + | +help: use fully qualified syntax to disambiguate + | +LL | fn c(_: ::Color) where C : Vehicle, C : Box { + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn c(_: ::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, _: ::Color) where X : Box; + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn e(&self, _: ::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, _: ::Color) where X : Box { } + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn f(&self, _: ::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, _: ::Color) where X : Box { } + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn d(&self, _: ::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: C, color: C::Color) { + //~^ ERROR ambiguous associated type `Color` in bounds of `C` +} + +fn dent_object(c: dyn BoxCar) { + //~^ ERROR ambiguous associated type + //~| ERROR the value of the associated types +} + +fn paint(c: C, d: C::Color) { + //~^ ERROR ambiguous associated type `Color` in bounds of `C` +} + +fn dent_object_2(c: dyn BoxCar) where ::Color = COLOR { + //~^ ERROR the value of the associated types + //~| ERROR equality constraints are not yet supported in `where` clauses +} + +fn dent_object_3(c: X) +where X: BoxCar, + X: Vehicle, + X: Box +{} // 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(c: dyn BoxCar) where ::Color = COLOR { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #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: C, color: C::Color) { + | ^^^^^^^^ ambiguous associated type `Color` + | +help: use fully qualified syntax to disambiguate + | +LL | fn dent(c: C, color: ::Color) { + | ~~~~~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn dent(c: C, color: ::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(c: dyn BoxCar) { + | ^^^^^^^^^^^ 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(c: dyn BoxCar) { + | ^^^^^^^^^^^^^^^^^^^ 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: C, d: C::Color) { + | ^^^^^^^^ ambiguous associated type `Color` + | +help: use fully qualified syntax to disambiguate + | +LL | fn paint(c: C, d: ::Color) { + | ~~~~~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | fn paint(c: C, d: ::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(c: dyn BoxCar) where ::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: 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: 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: 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 ::Assoc { br } = ::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 ::Assoc(n) = ::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 ::Assoc(n) = ::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 ::Assoc(n) = ::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 { + type Output; + + fn add(self, _: RHS) -> Self::Output; +} + +fn ice(a: A) { + let r = loop {}; + r = r + a; + //~^ ERROR the trait bound `(): Add` 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` is not satisfied + --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:23:11 + | +LL | r = r + a; + | ^ the trait `Add` 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: ::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; + fn bit_iter(self) -> ::Iter; +} + +impl BitIter for Vec { + type Iter = vec::IntoIter; + fn bit_iter(self) -> ::Iter { + self.into_iter() + } +} + +fn count(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) -> ::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>(x: I) -> Bar { + x.boo() +} + +fn foo_uint>(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: C) { +} + +fn blue_car>(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 `::Color == Blue` + --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10 + | +LL | fn b() { blue_car(ModelT); } + | ^^^^^^^^ type mismatch resolving `::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: C) { + | ^^^^^^^^^^ required by this bound in `blue_car` + +error[E0271]: type mismatch resolving `::Color == Black` + --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10 + | +LL | fn c() { black_car(ModelU); } + | ^^^^^^^^^ type mismatch resolving `::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: 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 + From; + type Repr2: From + From; + + fn method() { + Self::Repr::from(10); + Self::Repr2::from(10); + } +} + +fn function() { + 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) -> ::R; +} + +fn foo(g: G) -> isize + where G : GetToInt, ::R: ToInt +{ + ToInt::to_int(&g.get()) //~ ERROR E0277 +} + +fn bar(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) -> ::R; +} + +fn foo(g: G) -> isize + where G : GetToInt +{ + ToInt::to_int(&g.get()) //~ ERROR E0277 +} + +fn bar(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 `::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 `::R` + | | + | required by a bound introduced by this call + | +help: consider further restricting the associated type + | +LL | where G : 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) -> ::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) -> 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: B) -> ::T { + Bar::get(None::) +} + +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 ::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 ::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 ::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 { + fn eq(&self, u: &U) -> bool; +} + +impl MyEq<[B]> for [A] + where A : MyEq +{ + 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, Lhs: Deref +{ + fn eq(&self, other: &[B; 0]) -> bool { + MyEq::eq(&**self, other) + } +} + +struct DerefWithHelper { + pub helper: H, + pub marker: PhantomData, +} + +trait Helper { + fn helper_borrow(&self) -> &T; +} + +impl Helper for Option { + fn helper_borrow(&self) -> &T { + self.as_ref().unwrap() + } +} + +impl> Deref for DerefWithHelper { + type Target = T; + + fn deref(&self) -> &T { + self.helper.helper_borrow() + } +} + +pub fn check(x: T, y: T) -> bool { + let d: DerefWithHelper, 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) -> ::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>) -> 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) -> 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() -> () + where T : Foo, T : 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 { + Redirect { to: K }, + Root { value: K::Value, rank: usize }, +} + +fn get<'a,K:UnifyKey>,V>(table: &'a Vec>, key: &K) -> &'a Option { + 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; + 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 { + Redirect(K), + Root(K::Value, usize), +} + +fn get<'a,K:UnifyKey>,V>(table: &'a Vec>, key: &K) -> &'a Option { + match table[key.to_index()] { + VarValue::Redirect(ref k) => get(table, k), + VarValue::Root(ref v, _) => v, + } +} + +impl UnifyKey for usize { + type Value = Option; + 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) -> ::A; +} + +fn foo2(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(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(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) -> ::A; +} + +struct Bar; + +impl Foo for isize { + type A = usize; + fn boo(&self) -> usize { 42 } +} + +fn baz(x: &>::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(x: &>::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) -> ::A; +} + +struct Bar; + +impl Foo for isize { + type A = usize; + fn boo(&self) -> usize { + 42 + } +} + +fn foo1>(x: I) { + let _: Bar = x.boo(); +} + +fn foo2(x: I) { + let _: Bar = x.boo(); + //~^ ERROR mismatched types + //~| found associated type `::A` + //~| expected struct `Bar`, found associated type + //~| expected struct `Bar` +} + + +pub fn baz(x: &dyn Foo) { + 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 `::A` +help: consider constraining the associated type `::A` to `Bar` + | +LL | fn foo2>(x: I) { + | +++++++++ + +error[E0271]: type mismatch resolving `::A == Bar` + --> $DIR/associated-types-eq-3.rs:38:5 + | +LL | foo1(a); + | ^^^^ type mismatch resolving `::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>(x: I) { + | ^^^^^ required by this bound in `foo1` + +error[E0271]: type mismatch resolving `::A == Bar` + --> $DIR/associated-types-eq-3.rs:40:9 + | +LL | baz(&a); + | ^^ type mismatch resolving `::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` + +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::::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::::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 { + 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() +where + T: for<'x> TheTrait<&'x isize, A = &'x isize>, +{ + // ok for IntStruct, but not UintStruct +} + +fn bar() +where + T: for<'x> TheTrait<&'x isize, A = &'x usize>, +{ + // ok for UintStruct, but not IntStruct +} + +fn tuple_one() +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() +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() +where + T: for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>, +{ + // ok for tuple +} + +fn tuple_four() +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::(); + foo::(); //~ ERROR type mismatch +} + +pub fn call_bar() { + bar::(); //~ ERROR type mismatch + bar::(); +} + +pub fn call_tuple_one() { + tuple_one::(); +} + +pub fn call_tuple_two() { + tuple_two::(); +} + +pub fn call_tuple_three() { + tuple_three::(); +} + +pub fn call_tuple_four() { + tuple_four::(); +} + +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> >::A == &'x isize` + --> $DIR/associated-types-eq-hr.rs:87:5 + | +LL | foo::(); + | ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> >::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() + | --- 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> >::A == &'x usize` + --> $DIR/associated-types-eq-hr.rs:91:5 + | +LL | bar::(); + | ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> >::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() + | --- 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) -> ::A; +} + +pub struct Bar; + +impl Foo for char { + type A = Bar; + fn boo(&self) -> Bar { Bar } +} + +fn baz(x: &dyn Foo) -> 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) -> ::Value; +} + +trait Other { + fn uhoh(&self, foo: U, bar: ::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) -> ::Value; +} + +trait Other { + fn uhoh(&self, foo: U, bar: ::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(&self, foo: U, bar: ::Value) {} + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh(&self, foo: U, bar: ::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 {} +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; +} + +trait IteratorExt: Iterator + Sized { + fn by_ref(&mut self) -> ByRef { + ByRef(self) + } +} + +impl 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< ::Item > { + self.0.next() + } +} + +fn is_iterator_of>(_: &I) {} + +fn test>(mut it: I) { + is_iterator_of::(&it.by_ref()); +} + +fn test2, I2: Iterator>(mut it: I2) { + is_iterator_of::(&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) -> ::Value; +} + +fn 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(x: T, y: U) -> Get::Value {} + | ^^^^^^^^^^ help: use fully-qualified syntax: `::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: `::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: `::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: `::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: `::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(self, consumer: C) -> C::Result + where C: Consumer; +} + +pub trait Consumer { + 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) -> &::Value; + fn grab(&self) -> &::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) -> &::Value; +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +fn grab(x: &T) -> &::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) -> &::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) -> &::U; +} + +impl Grab for T { + type U = ::Value; + fn grab(&self) -> &::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) -> &::Value; +} + +struct Struct { + x: isize, +} + +impl Get for Struct { + type Value = isize; + fn get(&self) -> &isize { + &self.x + } +} + +impl Struct { + fn grab(x: &T) -> &::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) -> ::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; + + let b = &42isize as &dyn Foo; + //~^ ERROR the value of the associated type `B` (from trait `Foo`) must be specified + + let c = &42isize as &dyn Foo; + //~^ 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; + | ^^^^^^^^^^^^ help: specify the associated type: `Foo` + +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; + | ^^^^^^^^^^^ help: specify the associated type: `Foo` + +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` + +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 { + type Bar; + fn get_bar(&self) -> Self::Bar; +} + +fn f>(t: &T) { + let u: >::Bar = t.get_bar(); + //~^ ERROR the trait bound `T: Foo` 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` is not satisfied + --> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12 + | +LL | let u: >::Bar = t.get_bar(); + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T` + | +help: consider further restricting this bound + | +LL | fn f + Foo>(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; + + fn into_iter_x(self) -> Self::IntoIter; +} + +impl IntoIteratorX for Vec { + type Item = T; + type IntoIter = vec::IntoIter; + + fn into_iter_x(self) -> vec::IntoIter { + 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; +} + +fn is_iterator_of>(_: &I) {} + +struct Adapter { + iter: I, + found_none: bool, +} + +impl Iterator for Adapter where I: Iterator> { + type Item = T; + + fn next(&mut self) -> Option { + loop {} + } +} + +fn test_adapter>>(it: I) { + is_iterator_of::, _>(&it); // Sanity check + let adapter = Adapter { iter: it, found_none: false }; + is_iterator_of::(&adapter); // OK + is_iterator_of::, _>(&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 ` as Iterator>::Item == Option` + --> $DIR/associated-types-issue-20346.rs:34:5 + | +LL | fn test_adapter>>(it: I) { + | - this type parameter +... +LL | is_iterator_of::, _>(&adapter); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving ` as Iterator>::Item == Option` + | +note: expected this to be `Option` + --> $DIR/associated-types-issue-20346.rs:23:17 + | +LL | type Item = T; + | ^ + = note: expected enum `Option` + 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>(_: &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: ::Input) { + panic!() + } +} + +impl

(&self, pred: P) -> Splits where P: FnMut(&T) -> bool { + loop {} + } + + fn splitn2

(&self, n: u32, pred: P) -> SplitsN> 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(PhantomData); + +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> + where P: FnMut(&Self::Item) -> bool; +} + +impl SliceExt2 for [T] { + type Item = T; + + fn split2

(&self, pred: P) -> Splits where P: FnMut(&T) -> bool { + loop {} + } + + fn splitn2

(&self, n: usize, pred: P) -> SplitsN> 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 { from_utc(Y) } + +pub struct DateTime { pub offset: Off::State } +pub fn from_utc(offset: Off::State) -> DateTime { 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) -> >::Bar { + t +} + +pub fn free_and_use Foo<'a>, + F: for<'a> FnOnce(>::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; + +fn main() { + let _: &dyn I32Iterator = &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 ` as Iterator>::Item == i32` + --> $DIR/associated-types-overridden-binding-2.rs:6:43 + | +LL | let _: &dyn I32Iterator = &vec![42].into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` + | + = note: required for the cast from `std::vec::IntoIter` to the object type `dyn Iterator` + +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 {} +trait Bar: Foo {} //~ ERROR type annotations needed + +trait I32Iterator = Iterator; +trait U32Iterator = I32Iterator; //~ ERROR type annotations needed + +fn main() { + let _: &dyn I32Iterator; +} 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 `::Item == i32` + --> $DIR/associated-types-overridden-binding.rs:4:12 + | +LL | trait Bar: Foo {} + | ^^^^^^^^^^^^^^^ cannot satisfy `::Item == i32` + | +note: required by a bound in `Foo` + --> $DIR/associated-types-overridden-binding.rs:3:21 + | +LL | trait Foo: Iterator {} + | ^^^^^^^^^^ required by this bound in `Foo` + +error[E0284]: type annotations needed: cannot satisfy `::Item == i32` + --> $DIR/associated-types-overridden-binding.rs:7:21 + | +LL | trait U32Iterator = I32Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Item == i32` + | +note: required by a bound in `I32Iterator` + --> $DIR/associated-types-overridden-binding.rs:6:30 + | +LL | trait I32Iterator = Iterator; + | ^^^^^^^^^^ 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(a: T, x: T::A) {} //~ERROR associated type `A` not found +pub fn f2(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(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(a: T, x: T::A) {} + | ^^^^ ambiguous associated type `A` + | +help: use fully qualified syntax to disambiguate + | +LL | pub fn f2(a: T, x: ::A) {} + | ~~~~~~~~~~~~ +help: use fully qualified syntax to disambiguate + | +LL | pub fn f2(a: T, x: ::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(a: T, x: T::A) {} +pub fn f2(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(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(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(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 { + type A; + + fn get(&self, t: T) -> Self::A; +} + +fn foo<'a, I : for<'x> Foo<&'x isize>>( + x: >::A) +{ + let y: I::A = x; +} + +fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>( + x: >::A, + y: >::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 { + type A; + + fn get(&self, t: T) -> Self::A; +} + +fn foo2 Foo<&'x isize>>( + x: >::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 Foo<&'x isize>>( + x: >::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: >::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 { + type A; + + fn get(&self, t: T) -> Self::A; +} + +fn foo2 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 Foo<&'x isize>>( + x: >::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: >::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: >::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 { + type A; + + fn get(&self, t: T) -> Self::A; +} + +struct SomeStruct 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 Foo<&'x isize>> { +// field: Foo<&'y isize>>::A +// } + +struct YetAnotherStruct<'a, I: for<'x> Foo<&'x isize>> { + field: >::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: >::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(>::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: >::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: >::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 { + type A; + + fn get(&self, t: T) -> Self::A; +} + +trait SomeTrait Foo<&'x isize>> { + fn some_method(&self, arg: >::A); + //~^ ERROR cannot use the associated type of a trait with uninferred generic parameters +} + +trait AnotherTrait Foo<&'x isize>> { + fn some_method(&self, arg: >::A); +} + +trait YetAnotherTrait Foo<&'x isize>> { + fn some_method<'a>(&self, arg: >::A); +} + +trait Banana<'a> { + type Assoc: Default; +} + +struct Peach(std::marker::PhantomData); + +impl Banana<'a>> Peach { + fn mango(&self) -> >::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 { + type A; + + fn get(&self, t: T) -> Self::A; +} + +trait SomeTrait 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 Foo<&'x isize>> { + fn some_method(&self, arg: >::A); +} + +trait YetAnotherTrait Foo<&'x isize>> { + fn some_method<'a>(&self, arg: >::A); +} + +trait Banana<'a> { + type Assoc: Default; +} + +struct Peach(std::marker::PhantomData); + +impl Banana<'a>> Peach { + 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: >::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) -> >::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(_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(PhantomData); +impl B { + fn foo(_x: T::Item) where T: Trait { + COUNTER.fetch_add(10, SeqCst); + } +} + +// Where-clause attached to free fn. +fn c(_: T::Item) where T : Trait { + COUNTER.fetch_add(100, SeqCst); +} + +// Where-clause attached to defaulted and non-defaulted trait method. +trait AnotherTrait { + fn method(&self, _: T::Item) where T: Trait; + fn default_method(&self, _: T::Item) where T: Trait { + COUNTER.fetch_add(1000, SeqCst); + } +} +struct D; +impl AnotherTrait for D { + fn method(&self, _: T::Item) where T: Trait { + COUNTER.fetch_add(10000, SeqCst); + } +} + +// Where-clause attached to trait and impl containing the method. +trait YetAnotherTrait + where T : Trait +{ + fn method(&self, _: T::Item); + fn default_method(&self, _: T::Item) { + COUNTER.fetch_add(100000, SeqCst); + } +} +struct E(PhantomData); +impl YetAnotherTrait for E + where T : Trait +{ + fn method(&self, _: T::Item) { + COUNTER.fetch_add(1000000, SeqCst); + } +} + +// Where-clause attached to inherent impl containing the method. +struct F(PhantomData); +impl F where T : Trait { + fn method(&self, _: T::Item) { + COUNTER.fetch_add(10000000, SeqCst); + } +} + +// Where-clause attached to struct. +#[allow(dead_code)] +struct G where T : Trait { + data: T::Item, + phantom: PhantomData, +} + +fn main() { + A::foo::(22); + B::::foo(22); + c::(22); + D.method::(22); + D.default_method::(22); + E(PhantomData::).method(22); + E(PhantomData::).default_method(22); + F(PhantomData::).method(22); + G:: { 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 + Mul<(), Output = ()>; +} + +fn g>() { + let y: >::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 + 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 ::T { fn non_zero(self) -> bool { self != 0 } } +impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } +impl NonZero for ::T { fn non_zero(self) -> bool { self != 0 } } +impl NonZero for ::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 + '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 + 'a> +} + +impl<'a> Publisher<'a> for MyStruct<'a> { + type Output = u64; + fn subscribe(&mut self, t : Box + '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 +{ + fn foo (&self, t : TB) -> String; +} + +trait C : B<::TA> { } + +struct X; + +impl A for X +{ + type TA = i32; +} + +struct Y; + +impl C for Y { } + +// Both of these impls are required for successful compilation +impl B 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,J>(t: I) -> bool + where ::T : NonZero + // ^~~~~~~~~~~~~ canonical form is just J +{ + bar::() +} + +fn bar() -> 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 `::Value` in +// the trait definition even if there is no default method. + +trait Get { + type Value; +} + +trait Other { + fn okay(&self, foo: U, bar: ::Value) where Self: Get; + //~^ ERROR E0277 +} + +impl Get for () { + type Value = f32; +} + +impl Get for f64 { + type Value = u32; +} + +impl Other for () { + fn okay(&self, _foo: U, _bar: ::Value) { } +} + +impl Other for f64 { + fn okay(&self, _foo: U, _bar: ::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 `::Value` in +// the trait definition even if there is no default method. + +trait Get { + type Value; +} + +trait Other { + fn okay(&self, foo: U, bar: ::Value); + //~^ ERROR E0277 +} + +impl Get for () { + type Value = f32; +} + +impl Get for f64 { + type Value = u32; +} + +impl Other for () { + fn okay(&self, _foo: U, _bar: ::Value) { } +} + +impl Other for f64 { + fn okay(&self, _foo: U, _bar: ::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(&self, foo: U, bar: ::Value); + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn okay(&self, foo: U, bar: ::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 `::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(&self, foo: U, bar: ::Value) + where Self: Get; +} + +impl Get for () { + type Value = f32; +} + +impl Get for f64 { + type Value = u32; +} + +impl Other for () { + fn okay(&self, _foo: U, _bar: ::Value) { } +} + +impl Other for f64 { + fn okay(&self, _foo: U, _bar: ::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 { + type Bar; + fn get_bar() -> >::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 { + tester: T, + value: T::V, +} + +impl TesterPair { + fn new(tester: T, value: T::V) -> TesterPair { + 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 { + 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<::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 { + 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) -> ::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>(x: I) -> Bar { + x.boo() +} + +fn foo2(x: I) -> ::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) -> &::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 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 { + pub key: K, + pub value: K::Value, +} + +fn foo>,V : Clone>(node: &Node) -> Option { + node.value.clone() +} + +impl UnifyKey for i32 { + type Value = Option; +} + +impl UnifyKey for u32 { + type Value = Option; +} + +pub fn main() { + let node: Node = Node { key: 1, value: Some(22) }; + assert_eq!(foo(&node), Some(22)); + + let node: Node = 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(#[allow(unused_tuple_struct_fields)] K, K::Value); + +fn foo>,V : Clone>(node: &Node) -> Option { + node.1.clone() +} + +impl UnifyKey for i32 { + type Value = Option; +} + +impl UnifyKey for u32 { + type Value = Option; +} + +pub fn main() { + let node: Node = Node(1, Some(22)); + assert_eq!(foo(&node), Some(22)); + + let node: Node = 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 { 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: >::Type = make_any(); + let b: >::Type = make_any(); + let _c: >::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: >::Type = make_any(); + //~^ ERROR lifetime may not live long enough + let b: >::Type = make_any(); + let _c: >::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: >::Type = make_any(); + let b: >::Type = make_any(); + let _c: >::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: >::Type = make_any(); + let b: >::Type = make_any(); + let _c: >::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: >::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: >::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(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); +impl C for B { + 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) -> ::Value; +} + +fn foo(t: T) where ::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) -> ::Value; +} + +fn foo(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 `::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 `::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: T) where ::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; +} + +trait IteratorExt: Iterator + Sized { + fn by_ref(&mut self) -> ByRef { + ByRef(self) + } +} + +impl 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 { + type Item = A; + + fn next(&mut self) -> Option< ::Item > { + self.0.next() + } +} + +fn is_iterator_of>(_: &I) {} + +fn test>(mut it: I) { + is_iterator_of::(&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) -> ::T; +} + +impl Bar for isize { + type T = usize; + + fn get(_: Option) -> 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() 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() 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 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 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 Fn(<() as Foo<'a>>::Item) -> &'a i32>) { + //[object]~^ ERROR E0582 +} + +#[cfg(object)] +fn object2(_: Box Fn() -> <() as Foo<'a>>::Item>) { + //[object]~^ ERROR E0582 +} + +#[cfg(clause)] +fn clause1() where T: for<'a> Fn(<() as Foo<'a>>::Item) -> &'a i32 { + //[clause]~^ ERROR `Output` references lifetime `'a` +} + +#[cfg(clause)] +fn clause2() 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 Foo>() { + | ^^^^^^^^^^^^ + +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() where T: for<'a> Foo { + | ^^^^^^^^^^^^ + +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() where for<'a> T: Foo { + | ^^^^^^^^^^^^ + +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) { + | ^^^^^^^^^^^^ + +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 &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 &'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 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() 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() 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 Foo>() { + //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a` +} + +#[cfg(angle)] +fn angle1() where T: for<'a> Foo { + //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a` +} + +#[cfg(angle)] +fn angle2() where for<'a> T: Foo { + //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a` +} + +#[cfg(angle)] +fn angle3(_: &dyn for<'a> Foo) { + //[angle]~^ ERROR binding for associated type `Item` references lifetime `'a` +} + +#[cfg(paren)] +fn paren Fn() -> &'a i32>() { + //[paren]~^ ERROR binding for associated type `Output` references lifetime `'a` +} + +#[cfg(paren)] +fn paren1() where T: for<'a> Fn() -> &'a i32 { + //[paren]~^ ERROR binding for associated type `Output` references lifetime `'a` +} + +#[cfg(paren)] +fn paren2() 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 &i32>() { + //[elision]~^ ERROR E0106 +} + +struct Parameterized<'a> { x: &'a str } + +#[cfg(ok)] +fn ok1 Fn(&Parameterized<'a>) -> &'a i32>() { +} + +#[cfg(ok)] +fn ok2 Fn<(&'b Parameterized<'a>,), Output=&'a i32>>() { +} + +#[cfg(ok)] +fn ok3() where for<'a> Parameterized<'a>: Foo { +} + +#[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 = Result; + +pub enum Item<'a> { + Literal(&'a str) +} + +pub fn colon_or_space(s: &str) -> ParseResult<&str> { + unimplemented!() +} + +pub fn timezone_offset_zulu(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> { + 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, 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 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 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 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 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 &'a u32>, +} + +fn foo<'a>() -> Type<'a> { + loop {} +} + +fn bar(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 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 { + type Out: Default + ToString = T; +} + +impl Foo for () { +} + +impl Foo for () { + type Out = bool; +} + +fn main() { + assert_eq!( + <() as Foo>::Out::default().to_string(), + "0"); + assert_eq!( + <() as Foo>::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; + //~^ ERROR overflow evaluating the requirement `::B == _` +} +// (the error is shown twice for some reason) + +impl Tr for usize { + type B = &'static Self::A; + //~^ ERROR overflow evaluating the requirement `::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 `::B == _` + --> $DIR/defaults-cyclic-fail-1.rs:26:14 + | +LL | type A = Box; + | ^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `::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; + type B = Box; +} + +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; + //~^ ERROR overflow evaluating the requirement `::B == _` +} +// (the error is shown twice for some reason) + +impl Tr for usize { + type B = &'static Self::A; + //~^ ERROR overflow evaluating the requirement `::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 `::B == _` + --> $DIR/defaults-cyclic-fail-2.rs:27:14 + | +LL | type A = Box; + | ^^^^^^^^^^^^ + +error[E0275]: overflow evaluating the requirement `::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 _: ::A = 0u8; + let _: ::B = 0u8; + + let _: ::A = (); + let _: ::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; + type B = Box; + + 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 _: ::A = 0u8; + let _: ::B = Box::new(0u8); + + let _: ::A = Vec::<()>::new(); + let _: ::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; +} + +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::::new(); + let _item: <() as Tr>::Item = 0u8; + + let _container: ::Container = Vec::::new(); + let _item: ::Item = 0u16; + + let _container: ::Container = String::new(); + let _item: ::Item = 0u8; + + let _container: ::Container = Vec::<()>::new(); + let _item: ::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 `::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 `::A` + //~| NOTE this expression has type `::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 `::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 `::A` + | | + | expected associated type, found `()` + | + = note: expected associated type `::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 `::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 _: ::Foo = 0u8; + let _: ::Bar = (); + + let _: ::Foo = String::new(); + let _: ::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); +// In a `default impl`, assoc. types are defaulted as well, +// so their values can't be assumed. +default impl Tr for A { + fn make() -> u8 { 0 } + //~^ ERROR method `make` has an incompatible type for trait +} + +struct A2(T); +// ...same, but in the method body +default impl Tr for A2 { + fn make() -> Self::Ty { 0u8 } + //~^ ERROR mismatched types +} + +struct B(T); +// Explicitly defaulting the type does the same. +impl Tr for B { + default type Ty = bool; + + fn make() -> bool { true } + //~^ ERROR method `make` has an incompatible type for trait +} + +struct B2(T); +// ...same, but in the method body +impl Tr for B2 { + default type Ty = bool; + + fn make() -> Self::Ty { true } + //~^ ERROR mismatched types +} + +struct C(T); +// Only the method is defaulted, so this is fine. +impl Tr for C { + type Ty = bool; + + default fn make() -> bool { true } +} + +// Defaulted method *can* assume the type, if the default is kept. +struct D(T); +impl Tr for D { + default fn make() -> u8 { 0 } +} + +impl Tr for D { + fn make() -> u8 { 255 } +} + +struct E(T); +impl Tr for E { + 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 { + 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 _: as Tr>::Ty = 0u8; + //let _: as Tr>::Ty = 0u8; + + let _: as Tr>::Ty = 0u8; //~ error: mismatched types + let _: as Tr>::Ty = true; //~ error: mismatched types + let _: as Tr>::Ty = 0u8; //~ error: mismatched types + let _: as Tr>::Ty = true; //~ error: mismatched types + + let _: as Tr>::Ty = true; + + let _: as Tr>::Ty = 0u8; + let _: 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 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: ` as Tr>::Ty` + | +note: type in trait + --> $DIR/defaults-specialization.rs:9:18 + | +LL | fn make() -> Self::Ty { + | ^^^^^^^^ + = note: expected fn pointer `fn() -> 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: ` as Tr>::Ty` + | +note: type in trait + --> $DIR/defaults-specialization.rs:9:18 + | +LL | fn make() -> Self::Ty { + | ^^^^^^^^ + = note: expected fn pointer `fn() -> 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 `::Ty` because of return type +LL | 0u8 + | ^^^ expected associated type, found `u8` + | + = note: expected associated type `::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 ` as Tr>::Ty` because of return type + | + = note: expected associated type ` as Tr>::Ty` + found type `u8` + = help: consider constraining the associated type ` as Tr>::Ty` to `u8` or calling a method that returns ` 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 ` as Tr>::Ty` because of return type + | + = note: expected associated type ` as Tr>::Ty` + found type `bool` + +error[E0308]: mismatched types + --> $DIR/defaults-specialization.rs:87:32 + | +LL | let _: as Tr>::Ty = 0u8; + | ----------------- ^^^ expected associated type, found `u8` + | | + | expected due to this + | + = note: expected associated type ` as Tr>::Ty` + found type `u8` +help: a method is available that returns ` 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 _: as Tr>::Ty = true; + | ----------------- ^^^^ expected associated type, found `bool` + | | + | expected due to this + | + = note: expected associated type ` as Tr>::Ty` + found type `bool` +help: a method is available that returns ` 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 _: as Tr>::Ty = 0u8; + | ------------------ ^^^ expected associated type, found `u8` + | | + | expected due to this + | + = note: expected associated type ` as Tr>::Ty` + found type `u8` +help: a method is available that returns ` 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 _: as Tr>::Ty = true; + | ------------------ ^^^^ expected associated type, found `bool` + | | + | expected due to this + | + = note: expected associated type ` as Tr>::Ty` + found type `bool` +help: a method is available that returns ` 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 { + type Bar: Clone = Vec; + //~^ ERROR the trait bound `T: Clone` is not satisfied +} + +trait Bar: Sized { + // `(): Foo` might hold for some possible impls but not all. + type Assoc: Foo = (); + //~^ ERROR the trait bound `(): Foo` is not satisfied +} + +trait IsU8 {} +impl IsU8 for T {} + +// Test that mentioning the assoc. type inside where clauses is not allowed +trait C where + Vec: Clone, + Self::Assoc: IsU8, + bool: IsU8, +{ + type Assoc = u8; +} + +// Test that we get all expected errors if that default is unsuitable +trait D where + Vec: Clone, + Self::Assoc: IsU8, + bool: IsU8, +{ + type Assoc = NotClone; + //~^ ERROR the trait bound `NotClone: IsU8` 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 { + type Bar: Clone = Vec; + //~^ ERROR the trait bound `>::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 { + type Bar: Clone = Vec; + //~^ ERROR the trait bound `>::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 +where + Self::Bar: Clone, + Self::Baz: Clone, +{ + type Bar = Vec; + 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 +where + T: Clone, +{ + type Bar: Clone = Vec; + 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; + | ^^^^^^ the trait `Clone` is not implemented for `T` + | + = note: required because of the requirements on the impl of `Clone` for `Vec` +note: required by a bound in `Foo::Bar` + --> $DIR/defaults-suitability.rs:28:15 + | +LL | type Bar: Clone = Vec; + | ^^^^^ required by this bound in `Foo::Bar` +help: consider restricting type parameter `T` + | +LL | trait Foo { + | +++++++++++++++++++ + +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/defaults-suitability.rs:34:29 + | +LL | type Assoc: Foo = (); + | ^^ the trait `Foo` is not implemented for `()` + | +note: required by a bound in `Bar::Assoc` + --> $DIR/defaults-suitability.rs:34:17 + | +LL | type Assoc: Foo = (); + | ^^^^^^^^^ required by this bound in `Bar::Assoc` + +error[E0277]: the trait bound `NotClone: IsU8` is not satisfied + --> $DIR/defaults-suitability.rs:56:18 + | +LL | type Assoc = NotClone; + | ^^^^^^^^ the trait `IsU8` is not implemented for `NotClone` + | +note: required by a bound in `D::Assoc` + --> $DIR/defaults-suitability.rs:53:18 + | +LL | Self::Assoc: IsU8, + | ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc` +... +LL | type Assoc = NotClone; + | ----- required by a bound in this + +error[E0277]: the trait bound `>::Baz: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:65:23 + | +LL | type Bar: Clone = Vec; + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `>::Baz` + | + = note: required because of the requirements on the impl of `Clone` for `Vec<>::Baz>` +note: required by a bound in `Foo2::Bar` + --> $DIR/defaults-suitability.rs:65:15 + | +LL | type Bar: Clone = Vec; + | ^^^^^ required by this bound in `Foo2::Bar` +help: consider further restricting the associated type + | +LL | trait Foo2 where >::Baz: Clone { + | +++++++++++++++++++++++++++++++++++ + +error[E0277]: the trait bound `>::Baz: Clone` is not satisfied + --> $DIR/defaults-suitability.rs:74:23 + | +LL | type Bar: Clone = Vec; + | ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `>::Baz` + | + = note: required because of the requirements on the impl of `Clone` for `Vec<>::Baz>` +note: required by a bound in `Foo25::Bar` + --> $DIR/defaults-suitability.rs:74:15 + | +LL | type Bar: Clone = Vec; + | ^^^^^ required by this bound in `Foo25::Bar` +help: consider further restricting the associated type + | +LL | trait Foo25 where >::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 + AddAssign<&'static str> + From + 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 UncheckedCopy for T {} + +fn bug(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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 UncheckedCopy for T {} + +fn bug(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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 + AddAssign<&'static str> + From + 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 { + | ^ 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 + | ^^^^^^^ + +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 + | ^^^^^^^ + +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 Mirror for T { + type Image = T; +} + +#[cfg(bad)] +fn foo(_t: T) + where for<'a> &'a T: Mirror +{} + +#[cfg(good)] +fn foo(_t: T) + where for<'a> &'a T: Mirror +{} + +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> >::U: Clone, +{ + type U: ?Sized; + fn f(&self, x: &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> >::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> >::U: Clone, +{ + type U: ?Sized; + fn f(&self, x: &Self::U) { + ::clone(x); + } +} + +impl X<'_> for u32 //~ overflow evaluating the requirement `for<'b> u32: X<'b>` +where + for<'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> >::U: Clone, +{ + type U: ?Sized; +} +fn f<'a, T: X<'a> + ?Sized>(x: &>::U) { + //~^ ERROR the trait bound `for<'b> >::U: Clone` is not satisfied + <>::U>::clone(x); +} + +pub fn main() { + f::>("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> >::U: Clone` is not satisfied + --> $DIR/hr-associated-type-bound-object.rs:7:13 + | +LL | fn f<'a, T: X<'a> + ?Sized>(x: &>::U) { + | ^^^^^ the trait `for<'b> Clone` is not implemented for `>::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> >::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> >::V: Clone, + for<'b> >::V: Clone, +{ + type V: ?Sized; + fn g(&self, x: &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> >::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> >::W: Clone, +{ + type W: ?Sized; + fn h(&self, x: &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> >::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> >::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> >::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> >::U: Clone, +{ + type U: ?Sized; + fn f(x: &>::U) { + <>::U>::clone(x); + } +} + +impl 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> >::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 X<'_, T> for (S,) { + type U = str; + //~^ ERROR the trait bound `str: Clone` is not satisfied +} + +pub fn main() { + <(i32,) as X>::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; +} + +impl Cycle for Box { + type Next = Vec; +} + +impl Cycle for Vec { + type Next = Box; +} + +trait X<'a, T: Cycle + for<'b> X<'b, T>> +where + for<'b> >::U: Clone, + for<'b> T::Next: X<'b, T::Next>, + for<'b> >::U: Clone, +{ + type U: ?Sized; + fn f(x: &>::U) { + <>::U>::clone(x); + } +} + +impl X<'_, Vec> for S { + type U = str; + //~^ ERROR the trait bound `str: Clone` is not satisfied +} + +impl X<'_, Box> for S { + type U = str; + //~^ ERROR the trait bound `str: Clone` is not satisfied +} + +pub fn main() { + >>::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> >::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> >::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> >::U: Clone, +{ + type U: ?Sized; + fn f(x: &>::U) { + <>::U>::clone(x); + } +} + +impl 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>::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 X<'_, T> for (S,) { + | ^^^^^^^^ the trait `for<'b> X<'b, T>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | impl 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> >::Item: std::ops::Deref, +{ + type Item; + + fn bug(item: &Self::Item) -> () { + let x: T = **item; + &x as *const _; + } +} + +impl UnsafeCopy<'_, T> for T { + //~^ type mismatch resolving `::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 `::Target == T` + --> $DIR/hr-associated-type-projection-1.rs:13:33 + | +LL | impl UnsafeCopy<'_, T> for T { + | - this type parameter ^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type + | + = note: expected type parameter `T` + found associated type `::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> >::Item: std::ops::Deref, + | ^^^^^^^^^^ required by this bound in `UnsafeCopy` +help: consider further restricting this bound + | +LL | impl> 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 { + //~^ ERROR type mismatch resolving `::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 `::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 { + | ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32` +LL | +LL | bar() + | ----- return type was inferred to be `impl Bar` here + | + = note: expected associated type `::Item` + found type `i32` + = help: consider constraining the associated type `::Item` to `i32` or calling a method that returns `::Item` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html +help: consider constraining the associated type `::Item` to `i32` + | +LL | fn bar() -> impl Bar { + | ++++++++++++ + +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 Baz for (T,) {} + +trait Fiz {} +impl Fiz for bool {} + +trait Grault { + type A; + type B; +} + +impl 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 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 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 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 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 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) -> ::Product; +} + +impl Factory for f64 { + type Product = f64; + fn create(&self) -> f64 { *self * *self } +} + +impl Factory for (A, B) { + type Product = (::Product, ::Product); + fn create(&self) -> (::Product, ::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::State + >>(&self, value: &T) -> u64; +} + +pub trait Hash { + 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 { + type Output; + + fn from(src: Src) -> >::Output; +} + +trait To: Sized { + fn to>(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 + | ^^^ + | | + | 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 { + type Result; + + fn from(src: Src) -> Self::Result; +} + +trait To { + fn to( + self + ) -> >::Result where Dst: From { //~ 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 | ) -> >::Result where Dst: From { + | ^^^^^^^^^^ 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 { + | ^^^ required by this bound in `From` +help: consider further restricting `Self` + | +LL | ) -> >::Result where Dst: From, Self: Sized { + | +++++++++++++ +help: consider relaxing the implicit `Sized` restriction + | +LL | trait From { + | ++++++++ + +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> { + 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 { + //~^ 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 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = 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 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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 + '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) -> ::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) -> ::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 + '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 { + type Output; +} + +trait Sub { + 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 { + | ------------------- type parameter `Rhs` must be specified for this +... +LL | type Test = dyn Add + Sub; + | ^^^ help: set the type parameter to the desired type: `Sub` + | + = 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 { + | ------------------- type parameter `Rhs` must be specified for this +... +LL | type Test = dyn Add + Sub; + | ^^^ help: set the type parameter to the desired type: `Add` + | + = 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 + +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 + Sub; + | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ + +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 { inner: T::A } + +fn is_send() {} + +fn main() { + is_send::>(); +} 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<::Item> { + type Item; +} + +trait TheSuperTrait { + fn get(&self) -> T; +} + +impl TheTrait for i32 { + type Item = u32; +} + +impl TheSuperTrait for i32 { + fn get(&self) -> u32 { + *self as u32 + } +} + +fn foo>(t: &T) -> u32 { + t.get() +} + +fn main() { + foo::(&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; + //~^ 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; + | ------------- `Children` defined here ^^^^^^^^^ help: specify the associated types: `Hierarchy` + +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 {a:AType} + +pub trait A { + type B = C; + //~^ 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; + | ^^^^^^^^^^^^^^^^^^^^^^ 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 { + fn dummy(&self); +} + +trait Foo { + type A; + type B: Bar; + + fn get_b(&self) -> &Self::B; +} + +fn test_bar>(_: &B) {} + +fn test>(f: &F) { + test_bar(f.get_b()); +} + +trait Bar1 {} +trait Caz1 { + type A; + type B: Bar1; +} + +fn test1() where T: Caz1, U: Caz1 {} + +trait Bar2 {} +trait Caz2 { + type A; + type B: Bar2; +} +fn test2>() {} + +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 { + type O; +} + +trait Trait: Sized { + type A: MultiDispatch; + type B; + + fn new(u: U) -> >::O + where + Self::A: MultiDispatch; +} + +fn test>(b: i32) -> T +where + T::A: MultiDispatch, +{ + 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; + fn get(c: Self::ItemsIterator) { + c.into_iter(); + } +} + +trait DictLike2<'a> { + type ItemsIterator: Iterator; + + 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 { + type Output; + fn resolve(&self, input: I); +} + +pub trait ToRouting { + type Input; + type Routing : ?Sized = dyn Routing; + fn to_routing(self) -> Self::Routing; +} + +pub struct Mount> { + action: R, + _marker: PhantomData +} + +impl> Mount { + pub fn create>(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: ::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: ::Bar = 6665; + | ^^^^ expected associated type, found integer + | + = note: expected associated type `<::Fv as Foo>::Bar` + found type `{integer}` + = help: consider constraining the associated type `<::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(from: &U::From) -> U::From { + *from +} + +pub fn copy_any(t: &T) -> T { + copy::>(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::>(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(from: &U::From) -> U::From { + | ^^^^^ required by this bound in `copy` +help: consider restricting type parameter `T` + | +LL | pub fn copy_any(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::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() -> ::Out { loop {} } + +// ...and that it works with a blanket impl +trait Tr { + type Assoc; +} + +impl Tr for T { + type Assoc = (); +} + +fn g() -> ::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; +} + +trait Child {} + +struct ChildWrapper(T); +impl Child for ChildWrapper where T: Child {} + +struct ParentWrapper(T); +impl> Parent for ParentWrapper { + type Ty = A; + type Assoc = ChildWrapper; +} + +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<::Ring, Output = Self> { + type Ring: Ring; +} + +trait EuclideanSpace { + type Coordinates: Module; + type Real: Real; +} + +trait Translation { + fn to_vector(&self) -> E::Coordinates; + + fn powf(&self, n: ::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; +} + +trait TElement: Sized { + type ConcreteNode: TNode; +} + +trait DomTraversal { + type BorrowElement: Borrow; +} + +#[allow(dead_code)] +fn recalc_style_at() +where + E: TElement, + D: DomTraversal, +{ +} + +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; +} + +trait Bar {} + +fn x, 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; +} + +fn fails() +where + T: Test, +{ +} + +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; +} + +impl CanDecode for u8 { + fn read(rdr: &mut Foo) -> Option { Some(42) } +} + +impl CanDecode for u16 { + fn read(rdr: &mut Foo) -> Option { 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 { type BarT: Bar; } +impl Bar<()> for () { type BarT = (); } + +#[allow(dead_code)] +fn test>() { } +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: Copy { +} + +pub trait Complete { + type Assoc: Partial; +} + +impl Partial for T::Assoc where + T: Complete +{ +} + +impl 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; + | ^^^^^^^^^^^^^ required by this bound in `Complete::Assoc` +help: consider restricting type parameter `T` + | +LL | impl 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 { + type Out: Default + ToString + ?Sized = dyn ToString; //~ ERROR not satisfied +} + +impl Foo for () {} +impl Foo for () {} + +fn main() { + assert_eq!(<() as Foo>::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>::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, +{} + +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 ? +// - `Option: 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 Insertable for Option + 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 + where + Option<&'a T>: Insertable, +{ + type Values = 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 } + +impl<'a, U> Dummy for Foo<&'a U> + where &'a U: Insertable +{ +} + +impl 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 Insertable for Option + 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 + where + Option<&'a T>: Insertable, +{ + type Values = 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 } + +impl 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<::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 { + _inner: T::Slice, +} + +pub trait Bar: Sized { + type Slice: ?Sized; + + fn open(_: &Path); +} + +impl Bar for Foo { + type Slice = [u8]; + + fn open(_: &Path) { + 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: Sized + Mul + MulAssign {} +impl ClosedMul for T +where + T: Mul + MulAssign, +{ +} + +pub trait InnerSpace: ClosedMul<::Real> { + type Real; +} + +pub trait FiniteDimVectorSpace: ClosedMul<::Field> { + type Field; +} + +pub trait FiniteDimInnerSpace + : InnerSpace + FiniteDimVectorSpace::Real> { +} + +pub trait EuclideanSpace: ClosedMul<::Real> { + type Coordinates: FiniteDimInnerSpace + + Mul + + MulAssign; + + 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, +{ + type IntoIter; + fn get(&self) -> Self::IntoIter; +} + +struct Impl(Vec); + +impl Trait for Impl { + type IntoIter = ImplIntoIter; + fn get(&self) -> Self::IntoIter { + ImplIntoIter(self.0.clone()) + } +} + +struct ImplIntoIter(Vec); + +impl<'a> IntoIterator for &'a ImplIntoIter { + type Item = ::Item; + type IntoIter = std::iter::Cloned>; + 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; + + fn foo(&self) -> Self::Size; +} + +pub trait SubEncoder: Encoder { + type ActualSize; + + fn bar(&self) -> Self::Size; +} + +impl Encoder for T +where + T: SubEncoder, +{ + type Size = ::ActualSize; + //~^ ERROR: cannot add `::ActualSize` to `::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(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 `::ActualSize` to `::ActualSize` + --> $DIR/issue-54108.rs:19:17 + | +LL | type Size = ::ActualSize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `::ActualSize + ::ActualSize` + | + = help: the trait `Add` is not implemented for `::ActualSize` +note: required by a bound in `Encoder::Size` + --> $DIR/issue-54108.rs:4:16 + | +LL | type Size: Add; + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Encoder::Size` +help: consider further restricting the associated type + | +LL | T: 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(a: A, b: B) -> R where (A, B): Overload { + (a, b).overload() + } + + pub fn overload3(a: A, b: B, c: C) -> R where (A, B, C): Overload { + (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 { + type Output; +} + +impl ParseError for u32 { + type Output = (); +} + +impl Stream for () { + type Item = char; + type Error = u32; +} + +pub struct Lex<'a, I> + where I: Stream, + I::Error: ParseError, + <::Error as ParseError>::Output: 'a +{ + x: &'a >::Output +} + +pub struct Reserved<'a, I> where + I: Stream + 'a, + I::Error: ParseError, + <::Error as ParseError>::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: PhantomData, +} + +impl Fooifier for Foo { + type Assoc = Foo; +} + +trait Fooifier { + type Assoc; +} + +trait Barifier { + fn barify(); +} + +impl Barifier for Bar { + fn barify() { + println!("All correct!"); + } +} + +impl Bar<::Assoc> { + fn this_shouldnt_crash() { + ::Assoc>>::barify(); + } +} + +fn main() { + Bar::::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: +//~^ ERROR the trait bound `Bug: Foo` is not satisfied +//~| ERROR the trait bound `Bug: Foo` is not satisfied + Service::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(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: +LL | | +LL | | +LL | | Service::OnlyFoo> + | |______________________________________________^ the trait `Foo` is not implemented for `Bug` + | +help: consider further restricting this bound + | +LL | pub trait ThriftService: + | +++++ + +error[E0277]: the trait bound `Bug: Foo` is not satisfied + --> $DIR/issue-59324.rs:11:1 + | +LL | / pub trait ThriftService: +LL | | +LL | | +LL | | Service::OnlyFoo> +... | +LL | | +LL | | } + | |_^ the trait `Foo` is not implemented for `Bug` + | +help: consider further restricting this bound + | +LL | pub trait ThriftService: + | +++++ + +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: + | +++++ + +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/issue-59324.rs:23:29 + | +LL | fn with_factory(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: + | +++++ + +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(>::A) -> >::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(>::A) -> >::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; + + 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 {} + +trait MyTrait { + type This = Self; //~ error: size for values of type `Self` cannot be known + fn something>(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 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) -> &'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(::Type) where Self: ; +//~^ ERROR the trait bound `Bar: 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: Foo` is not satisfied + --> $DIR/issue-64855.rs:5:19 + | +LL | pub struct Bar(::Type) where Self: ; + | ^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bar` + +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<::MpuConfig> = None; + let valref: &mut ::MpuConfig = val.as_mut().unwrap(); + + // // This causes a different ICE (but its similar if you squint right): + // // + // // `Unimplemented` selecting `Binder()` during codegen + // + // writer.my_write(valref) + + // This one causes the ICE: + // FulfillmentError(Obligation(predicate=Binder(TraitPredicate()), + // depth=1),Unimplemented) + let closure = |config: &mut ::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 ::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<::MpuConfig> = None; + let valref: &mut ::MpuConfig = val.as_mut().unwrap(); + + // // This causes a different ICE (but its similar if you squint right): + // // + // // `Unimplemented` selecting `Binder()` 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()), + // depth=1),Unimplemented) + /*let closure = |config: &mut ::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 ParseError for T { + type StreamError = (); +} + +trait Stream { + type Item; + type Error: ParseError; +} + +trait Parser +where + ::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(core::marker::PhantomData<(A, B)>); + +impl Parser for AndThen +where + A: Stream, + B: Into<::StreamError>, +{ + type PartialState = (); +} + +fn expr() -> impl Parser +where + A: Stream::Item>, +{ + AndThen::(core::marker::PhantomData) +} + +fn parse_mode_impl() +where + ::Error: ParseError, + A: Stream::Item>, +{ + Parser::parse_mode(&expr::(), 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 Broken for T { + type Assoc = (); + fn broken(&self) where Self::Assoc: Foo { + let _x: ::Bar; + } +} + +fn main() { + let _m: &dyn Broken = &(); +} 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> +{ + Variant(MyCow<'a, _Recursive<'a>>), +} + +pub struct Wrapper(T); + +pub struct MyCow<'a, T: ToOwned> + 'a>(Wrapper>); + +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; +} +trait Bar2 { + type Ok; +} + +struct Foo; +struct Foo2; + +impl Bar for Foo { + type Ok = (); + type Sibling = Foo2; + //~^ ERROR type mismatch resolving `::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 `::Ok == char` + --> $DIR/issue-72806.rs:14:20 + | +LL | type Sibling = Foo2; + | ^^^^ type mismatch resolving `::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; + | ^^^^^^^ 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; + 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 Relation { + pub fn map D2 + 'static, D2: 'static>( + self, + f: F, + ) -> Relation> { + self.map_dr(move |x, r| (f(x), r)) + } + } + + impl> Relation { + pub fn semijoin, R2, R3: AddAssign>( + self, + other: Relation, + ) -> Relation> + where + C::R: Mul, + { + 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 { + _left: LC, + _right: RC, + } + impl< + LC: Op, + RC: Op, + K: 'static, + LD: 'static, + LR: AddAssign + Mul, + RD: 'static, + RR: AddAssign, + OR: AddAssign, + > Op for Join + { + type D = (K, LD, RD); + type R = OR; + } + impl> Relation { + pub fn join, D2: 'static, OR: AddAssign>( + self, + other: Relation, + ) -> Relation> + where + C::R: Mul, + { + Relation { + inner: Join { + _left: self.inner, + _right: other.inner, + }, + } + } + } + } + mod map { + use super::Op; + use crate::core::Relation; + use std::ops::AddAssign; + struct Map { + _inner: C, + _op: MF, + } + impl< + D1, + R1, + D2: 'static, + R2: AddAssign, + C: Op, + MF: Fn(D1, R1) -> (D2, R2), + > Op for Map + { + type D = D2; + type R = R2; + } + impl Relation { + pub fn map_dr (D2, R2), D2: 'static, R2: AddAssign>( + self, + f: F, + ) -> Relation> { + Relation { + inner: Map { + _inner: self.inner, + _op: f, + }, + } + } + } + } + use std::ops::AddAssign; + pub trait Op { + type D: 'static; + type R: AddAssign; + } + } + pub use self::operator::Op; + #[derive(Clone)] + pub struct Relation { + 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 { + type Associated; +} + +struct Impl; +impl Foo for Impl {} +impl Trait for Impl { + type Associated = (); +} +impl DerivedTrait for Impl {} +impl GenericTrait 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 { + Impl +} + +fn accepts_trait>(_: T) {} +fn accepts_generic_trait>(_: T) {} + +fn check_generics(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, +{ + accepts_trait(a); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_trait(b); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_trait(c); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_trait(d); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_generic_trait(e); + //~^ ERROR type mismatch resolving `>::Associated == ()` + + accepts_generic_trait(f); + //~^ ERROR type mismatch resolving `>::Associated == ()` + + accepts_generic_trait(g); + //~^ ERROR type mismatch resolving `>::Associated == ()` +} + +fn main() { + accepts_trait(returns_opaque()); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_trait(returns_opaque_derived()); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_trait(returns_opaque_foo()); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_trait(returns_opaque_derived_foo()); + //~^ ERROR type mismatch resolving `::Associated == ()` + + accepts_generic_trait(returns_opaque_generic()); + //~^ ERROR type mismatch resolving ` as GenericTrait<()>>::Associated == ()` + + accepts_generic_trait(returns_opaque_generic_foo()); + //~^ ERROR type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` + + accepts_generic_trait(returns_opaque_generic_duplicate()); + //~^ ERROR type mismatch resolving ` + GenericTrait 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 `::Associated == ()` + --> $DIR/issue-87261.rs:56:5 + | +LL | accepts_trait(a); + | ^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `::Associated` +note: required by a bound in `accepts_trait` + --> $DIR/issue-87261.rs:43:27 + | +LL | fn accepts_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` +help: consider constraining the associated type `::Associated` to `()` + | +LL | A: Trait + 'static, + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `::Associated == ()` + --> $DIR/issue-87261.rs:59:5 + | +LL | accepts_trait(b); + | ^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `::Associated` + = help: consider constraining the associated type `::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) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` + +error[E0271]: type mismatch resolving `::Associated == ()` + --> $DIR/issue-87261.rs:62:5 + | +LL | accepts_trait(c); + | ^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `::Associated` +note: required by a bound in `accepts_trait` + --> $DIR/issue-87261.rs:43:27 + | +LL | fn accepts_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` +help: consider constraining the associated type `::Associated` to `()` + | +LL | C: Trait + Foo, + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `::Associated == ()` + --> $DIR/issue-87261.rs:65:5 + | +LL | accepts_trait(d); + | ^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `::Associated` + = help: consider constraining the associated type `::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) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` + +error[E0271]: type mismatch resolving `>::Associated == ()` + --> $DIR/issue-87261.rs:68:5 + | +LL | accepts_generic_trait(e); + | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `>::Associated` +note: required by a bound in `accepts_generic_trait` + --> $DIR/issue-87261.rs:44:46 + | +LL | fn accepts_generic_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` +help: consider constraining the associated type `>::Associated` to `()` + | +LL | E: GenericTrait<(), Associated = ()> + 'static, + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `>::Associated == ()` + --> $DIR/issue-87261.rs:71:5 + | +LL | accepts_generic_trait(f); + | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `>::Associated` +note: required by a bound in `accepts_generic_trait` + --> $DIR/issue-87261.rs:44:46 + | +LL | fn accepts_generic_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` +help: consider constraining the associated type `>::Associated` to `()` + | +LL | F: GenericTrait<(), Associated = ()> + Foo, + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `>::Associated == ()` + --> $DIR/issue-87261.rs:74:5 + | +LL | accepts_generic_trait(g); + | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type `>::Associated` + = help: consider constraining the associated type `>::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) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` + +error[E0271]: type mismatch resolving `::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 `::Associated` +note: required by a bound in `accepts_trait` + --> $DIR/issue-87261.rs:43:27 + | +LL | fn accepts_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` +help: consider constraining the associated type `::Associated` to `()` + | +LL | fn returns_opaque() -> impl Trait + 'static { + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `::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 `::Associated` +note: required by a bound in `accepts_trait` + --> $DIR/issue-87261.rs:43:27 + | +LL | fn accepts_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` +help: consider constraining the associated type `::Associated` to `()` + | +LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `::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 `::Associated` +note: required by a bound in `accepts_trait` + --> $DIR/issue-87261.rs:43:27 + | +LL | fn accepts_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` +help: consider constraining the associated type `::Associated` to `()` + | +LL | fn returns_opaque_foo() -> impl Trait + Foo { + | +++++++++++++++++ + +error[E0271]: type mismatch resolving `::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 `::Associated` + = help: consider constraining the associated type `::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) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` + +error[E0271]: type mismatch resolving ` 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 ` as GenericTrait<()>>::Associated` +note: required by a bound in `accepts_generic_trait` + --> $DIR/issue-87261.rs:44:46 + | +LL | fn accepts_generic_trait>(_: T) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` +help: consider constraining the associated type ` as GenericTrait<()>>::Associated` to `()` + | +LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static { + | +++++++++++++++++ + +error[E0271]: type mismatch resolving ` + 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 ` + 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) {} + | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` +help: consider constraining the associated type ` + Foo as GenericTrait<()>>::Associated` to `()` + | +LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo { + | +++++++++++++++++ + +error[E0271]: type mismatch resolving ` + GenericTrait as GenericTrait<()>>::Associated == ()` + --> $DIR/issue-87261.rs:97:5 + | +LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait { + | ---------------------------------------- the found opaque type +... +LL | accepts_generic_trait(returns_opaque_generic_duplicate()); + | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type + | + = note: expected unit type `()` + found associated type ` + GenericTrait as GenericTrait<()>>::Associated` + = help: consider constraining the associated type ` + GenericTrait 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) {} + | ^^^^^^^^^^^^^^^ 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(pub i32); + +impl Trait for TraitImpl +where [();N/2]:, +{ + type R = Self; + fn func(self)->Self::R { + self + } +} + +fn sample(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 { + fn create() -> Self; +} + +pub fn oh_no<'a, T>() +where + Wrap<'a>: Associate, + as Associate>::Associated: Create, +{ + 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: Mul + Div {} +trait Y: Div { + type A; +} +trait Z: Div { + type A; + type B; +} +trait Fine: Div {} + +type Foo = dyn Add + Sub + X + Y; +//~^ ERROR only auto traits can be used as additional traits in a trait object +//~| ERROR the value of the associated types +type Bar = dyn Add + Sub + X + Z; +//~^ ERROR only auto traits can be used as additional traits in a trait object +//~| ERROR the value of the associated types +type Baz = dyn Add + Sub + Y; +//~^ ERROR only auto traits can be used as additional traits in a trait object +//~| ERROR the value of the associated types +type Bat = dyn Add + Sub + Fine; +//~^ ERROR only auto traits can be used as additional traits in a trait object +//~| ERROR the value of the associated types +type Bal = dyn X; +//~^ 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 = dyn Add + Sub + X + Y; + | -------- ^^^^^^^^ 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 + Sub + X + Y {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit + +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 = dyn Add + Sub + X + Y; + | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ 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 = dyn Add + Sub + X + Y; + | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ + +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 = dyn Add + Sub + X + Z; + | -------- ^^^^^^^^ 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 + Sub + X + Z {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit + +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 = dyn Add + Sub + X + Z; + | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ 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 = dyn Add + Sub + X + Z; + | ^^^^^^ +help: specify the associated types + | +LL | type Bar = dyn Add + Sub + X + Z; + | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +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 = dyn Add + Sub + Y; + | -------- ^^^^^^^^ 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 + Sub + Y {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit + +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 = dyn Add + Sub + Y; + | ^^^^^^^^ ^^^^^^^^ ^^^^^^ 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 = dyn Add + Sub + Y; + | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ + +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 = dyn Add + Sub + Fine; + | -------- ^^^^^^^^ 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 + Sub + Fine {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit + +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 = dyn Add + Sub + Fine; + | ^^^^^^^^ ^^^^^^^^ associated type `Output` must be specified + | | + | associated type `Output` must be specified + | +help: specify the associated types + | +LL | type Bat = dyn Add + Sub + Fine; + | ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ + +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 = dyn X; + | ^^^^^^ 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 { + 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>>>; +} +impl<'r, T: FromRequest<'r>> FromRequest<'r> for Option { + type Error = (); + fn from_request<'life0>( + request: &'r Request<'life0>, + ) -> Pin>>> { + 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 { + 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>>>; +} +pub struct S { + _marker: std::marker::PhantomData, +} +impl<'r, T: FromRequest<'r>> S { + 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(addr: A) { + let _ = addr.to_socket_addr().await; +} +pub trait ToSocketAddr { + type Future: Future; + 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(self, _fun: F) -> AndThen { + unimplemented!() + } +} +struct AndThen { + _marker: std::marker::PhantomData, +} +pub async fn run(_: 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 Yokeable<'a>> { + _marker: std::marker::PhantomData, +} +impl Yokeable<'a>> Yoke { + pub fn project

( + &self, + _f: for<'a> fn(&>::Output, &'a ()) ->

>::Output, + ) -> Yoke

+ 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 Yokeable<'a>> { + _yokeable: Y, +} + +impl Yokeable<'a>> Yoke { + pub fn project<'this, P>( + &'this self, + _f: for<'a> fn(>::Output, &'a ()) ->

>::Output, + ) -> Yoke

+ 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 Value for T {} + +trait Distance +where + Self: PartialOrd<::Value>, + Self: PartialOrd, +{ + type Value: Value; +} + +impl Distance for T { + type Value = T; +} + +trait Proximity { + 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 BoxedDsl for T +where + T: BoxedDsl, +{ + type Output = ::Output; +} + +trait HandleUpdate {} + +impl HandleUpdate for T where T: BoxedDsl {} + +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 = >::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 +// >::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 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+?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 = &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) { + // To prove + // `dyn SVec: SVec` + // we need to show + // `dyn SVec as Index>::Output == as SVec>::Item` + // which, with the current normalization strategy, has to be eagerly + // normalized to: + // `dyn SVec as Index>::Output == T`. + let _ = s.len(); +} + +trait SVec: Index::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>>` +// - This requires proving `Square>: Sized` so that the first impl +// applies +// - This requires Providing `Square>` is well-formed, so that we +// can use the `Sized` bound on `Mul::Output` +// - This requires proving `Square: 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 { + type Output; +} + +pub trait IsGreaterOrEqual { + type Output; +} + +pub type Square = ::Output; +pub type GrEq = >::Output; + +impl IsGreaterOrEqual for A { + type Output = (); +} + +impl PrivateSquareRoot for U +where + U: Mul, + Square: Mul, + GrEq>>: 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 + ::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 | ::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; +} +trait Bar2 { + type Ok; +} + +struct Foo; +struct Foo2; + +impl Bar for Foo { + type Ok = (); + type Sibling = Foo2; + //~^ ERROR type mismatch resolving `::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 `::Ok == ()` + --> $DIR/point-at-type-on-obligation-failure.rs:14:20 + | +LL | type Sibling = Foo2; + | ^^^^ type mismatch resolving `::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; + | ^^^^^^^^^^^ 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 { pub data: [T; 1] } + +impl Pixel for Luma { + type Subpixel = T; +} + +pub struct ImageBuffer { + pixels: P, + c: Container, +} + +pub trait GenericImage: Sized { + type Pixel: Pixel; +} + +pub trait Pixel: Copy + Clone { + type Subpixel: Primitive; +} + +pub trait Primitive: Copy + PartialOrd + Clone { +} + +impl GenericImage for ImageBuffer +where P: Pixel + 'static, + Container: Deref + DerefMut, + P::Subpixel: 'static { + + type Pixel = P; +} + +impl Primitive for u8 { } + +impl ImageBuffer +where P: Pixel + 'static, + P::Subpixel: 'static, + Container: Deref +{ + pub fn pixels<'a>(&'a self) -> Pixels<'a, Self> { + loop { } + } + + pub fn pixels_mut(&mut self) -> PixelsMut

{ + 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(image: &ImageBuffer>) + -> ImageBuffer, Vec> +where Pix: Pixel + '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 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 { + type Output; +} +pub type Filter = >::Output; +impl FilterDsl for T +where + T: Table, + T::Query: FilterDsl, +{ + type Output = Filter; +} +impl FilterDsl for AlternateQuery { + type Output = &'static str; +} + +pub trait HandleDelete { + type Filter; +} +impl HandleDelete for T +where + T: Table, + T::Query: FilterDsl, + Filter: , +{ + type Filter = Filter; +} + +fn main() { + let x: ::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() {>::bar::<'static, char>} defined here +... +LL | let x: () = >::bar::<'static, char>; + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {>::bar::<'static, char>}` +help: use parentheses to call this function + | +LL | let x: () = >::bar::<'static, char>(); + | ++ + +error[E0308]: mismatched types + --> $DIR/substs-ppaux.rs:25:17 + | +LL | fn bar<'a, T>() where T: 'a {} + | --------------------------- fn() {>::bar::<'static, char>} defined here +... +LL | let x: () = >::bar::<'static, char>; + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {>::bar::<'static, char>}` +help: use parentheses to call this function + | +LL | let x: () = >::bar::<'static, char>(); + | ++ + +error[E0308]: mismatched types + --> $DIR/substs-ppaux.rs:33:17 + | +LL | fn baz() {} + | -------- fn() {>::baz} defined here +... +LL | let x: () = >::baz; + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {>::baz}` +help: use parentheses to call this function + | +LL | let x: () = >::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 | >::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: () = >::bar::<'static, char>; + //[verbose]~^ ERROR mismatched types + //[verbose]~| expected unit type `()` + //[verbose]~| found fn item `fn() {>::bar::}` + //[normal]~^^^^ ERROR mismatched types + //[normal]~| expected unit type `()` + //[normal]~| found fn item `fn() {>::bar::<'static, char>}` + + + let x: () = >::bar::<'static, char>; + //[verbose]~^ ERROR mismatched types + //[verbose]~| expected unit type `()` + //[verbose]~| found fn item `fn() {>::bar::}` + //[normal]~^^^^ ERROR mismatched types + //[normal]~| expected unit type `()` + //[normal]~| found fn item `fn() {>::bar::<'static, char>}` + + let x: () = >::baz; + //[verbose]~^ ERROR mismatched types + //[verbose]~| expected unit type `()` + //[verbose]~| found fn item `fn() {>::baz}` + //[normal]~^^^^ ERROR mismatched types + //[normal]~| expected unit type `()` + //[normal]~| found fn item `fn() {>::baz}` + + let x: () = foo::<'static>; + //[verbose]~^ ERROR mismatched types + //[verbose]~| expected unit type `()` + //[verbose]~| found fn item `fn() {foo::}` + //[normal]~^^^^ ERROR mismatched types + //[normal]~| expected unit type `()` + //[normal]~| found fn item `fn() {foo::<'static>}` + + >::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() {>::bar::} defined here +... +LL | let x: () = >::bar::<'static, char>; + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {>::bar::}` +help: use parentheses to call this function + | +LL | let x: () = >::bar::<'static, char>(); + | ++ + +error[E0308]: mismatched types + --> $DIR/substs-ppaux.rs:25:17 + | +LL | fn bar<'a, T>() where T: 'a {} + | --------------------------- fn() {>::bar::} defined here +... +LL | let x: () = >::bar::<'static, char>; + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {>::bar::}` +help: use parentheses to call this function + | +LL | let x: () = >::bar::<'static, char>(); + | ++ + +error[E0308]: mismatched types + --> $DIR/substs-ppaux.rs:33:17 + | +LL | fn baz() {} + | -------- fn() {>::baz} defined here +... +LL | let x: () = >::baz; + | -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {>::baz}` +help: use parentheses to call this function + | +LL | let x: () = >::baz(); + | ++ + +error[E0308]: mismatched types + --> $DIR/substs-ppaux.rs:41:17 + | +LL | fn foo<'z>() where &'z (): Sized { + | -------------------------------- fn() {foo::} defined here +... +LL | let x: () = foo::<'static>; + | -- ^^^^^^^^^^^^^^ expected `()`, found fn item + | | + | expected due to this + | + = note: expected unit type `()` + found fn item `fn() {foo::}` +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 | >::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 + Sub + Mul + Div {} +//~^ ERROR the size for values of type `Self` cannot be known at compilation time + +impl ArithmeticOps for T where T: Add + Sub + Mul + Div { + // 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 + Sub + Mul + Div {} + | ^^^^^^^^^^^^^^^^ 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 { + | ^^^^^^^^^^ required by this bound in `Add` +help: consider further restricting `Self` + | +LL | trait ArithmeticOps: Add + Sub + Mul + Div + 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 IntoIt for I { + type Item = (); +} + +trait BaseGraph +where + ::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 + ::U: Copy, +{ + type V: A; +} + +fn main() {} -- cgit v1.2.3

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>(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); + +trait Tr { + fn present(&self) {} +} + +impl Tr for Foo { + 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: &T) +{ + want_x(t); +} + +fn have_x_want_y>(t: &T) +{ + want_y(t); //~ ERROR type mismatch +} + +fn have_y_want_x>(t: &T) +{ + want_x(t); //~ ERROR type mismatch +} + +fn have_y_want_y>(t: &T) +{ + want_y(t); +} + +fn have_xy_want_x>(t: &T) +{ + want_x(t); +} + +fn have_xy_want_y>(t: &T) +{ + want_y(t); +} + +fn have_xy_want_xy>(t: &T) +{ + want_x(t); + want_y(t); +} + +fn want_x>(t: &T) { } + +fn want_y>(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 `::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 `::Y` +note: required by a bound in `want_y` + --> $DIR/associated-types-multiple-types-one-trait.rs:44:17 + | +LL | fn want_y>(t: &T) { } + | ^^^^^ required by this bound in `want_y` +help: consider constraining the associated type `::Y` to `i32` + | +LL | fn have_x_want_y>(t: &T) + | +++++++++ + +error[E0271]: type mismatch resolving `::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 `::X` +note: required by a bound in `want_x` + --> $DIR/associated-types-multiple-types-one-trait.rs:42:17 + | +LL | fn want_x>(t: &T) { } + | ^^^^^ required by this bound in `want_x` +help: consider constraining the associated type `::X` to `u32` + | +LL | fn have_y_want_x>(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) where + X: IntoIterator, + <::Iter as Iterator>::Item: Bound, +{ +} + +fn bar(x: X) where + T: Bound, + I: Iterator, + X: IntoIterator, +{ + +} + +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) -> ::Value; +} + +struct Struct { + x: isize, +} + +impl Struct { + fn uhoh(foo: ::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(foo: ::Value) {} + | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn uhoh(foo: ::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 `::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(&self, foo: U, bar: ::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(&self, foo: U, bar: ::Value) {} + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh(&self, foo: U, bar: ::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 `::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(&self, foo: U, bar: ::Value) {} + //~^ ERROR the trait bound `Self: Get` is not satisfied +} + +impl Other for T { + fn uhoh(&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(&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(&self, foo: U, bar: ::Value) {} + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` + | +help: consider further restricting `Self` + | +LL | fn uhoh(&self, foo: U, bar: ::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 { + type R; + + fn dummy(&self, a: A) -> Self::R { loop { } } +} + +fn foo() + where T : FnLike<::Opposite, R=bool> +{ + bar::(); +} + +fn bar() + where T : FnLike +{} + +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(PhantomData); + +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> + where P: FnMut(&Self::Item) -> bool; +} + +impl SliceExt2 for [T] { + type Item = T; + + fn split2